#!/usr/bin/env python
# coding=UTF-8
import random
import logging
import json
import time
import urllib
import datetime

import config
import dao

from nsq.http import nsqd
import redisco
from redisco.containers import List, Hash
import copy

def get_last_data(reader, bid, uid, data):
    user_info = Hash("%s_%s" % (bid, uid))
    rid = user_info['rid']
    if not rid:
        rid = data.get("rid", "")
    room = Hash("r:%s" % rid)
    game_type = room['game_type']
    if game_type == 'zzmj':
        tdh = ZZMaJiang(rid, bid)
    elif game_type == 'hzmj':
        tdh = HZMaJiang(rid, bid)
    elif game_type == 'csmj':
        tdh = CSMaJiang(rid, bid)
    elif game_type == 'pdk':
        tdh = PaoDeKuai(rid, bid)
    else:
        tdh = MaJiang(rid, bid)
    last_get_user = tdh.room['last_get_user']
    last_put_user = tdh.room['last_put_user']
    pubdata = {'act':'get_last_data', 'rid':rid, 'last_player':last_get_user, 'last_put_user':last_put_user}
    all_player_data = []
    l = List("r:%s:p" % rid)
    members = l.members
    for member in members:
        p = Player(member, bid, rid)
        player_data = p.get_data()
        eat_list = []
        eat_data_list = player_data['eat']
        for eat_data in eat_data_list:
            eat_list.append(eat_data.split(","))
        player_data['eat'] = eat_list
        if member != uid:
            player_data['current_card'] = ["*"] * len(player_data['current_card'])
            #player_data['dark_bar'] = ["*"] * len(player_data['dark_bar'])
        if game_type == 'pdk':
            del player_data['out_card']
            del player_data['dark_bar']
            del player_data['white_bar']
            del player_data['pair']
        player_data['status'] = 1
        all_player_data.append(player_data)
    tips = []
    dark_bar = []
    eat_card = []
    last_put_card = ''
    stop_pop_user = tdh.room['stop_pop_user']
    
    if game_type == 'pdk':
        tips = []
        if not last_put_user:
            last_put_user = stop_pop_user
        pubdata['last_player'] = stop_pop_user
        pubdata['last_put_user'] = last_put_user
        pubdata['put_type'] = ''
        last_put_card = tdh.room['last_put_card']
        if not last_put_card:
            last_put_card = []
        else:
            last_put_card = last_put_card.split(",")
        pubdata['last_put_card'] = last_put_card
    else:
        if stop_pop_user == str(uid):
            tips = tdh.room['stop_pop_act'].split(",")
            if tips:
                p = Player(uid, bid, rid)
                current_card = p.current_card.members
                if 'dark_bar' in tips:
                    dark_bar = tdh.check_init_dark_bar(current_card)
                if "eat" in tips:
                    last_put_player = Player(last_put_user, bid, rid)
                    last_put_card = last_put_player.out_card.members[-1]
                    eat_card = tdh.get_eat_card(current_card, last_put_card)
                if "bar_win" in tips:
                    tips.extend(['pair_bar_win'])
        pubdata["eat_card"] = eat_card
        pubdata["dark_bar"] = dark_bar
        pubdata["left_card"] = len(tdh.current_card)
        pubdata["card"] = last_put_card
    dealer = tdh.room['dealer']
    if not dealer:
        dealer = ''
    pubdata["dealer"] = dealer 
    pubdata["tips"] = tips
    pubdata["all_player_data"] = all_player_data
    pubdata["game_round"] = room['game_round']
    pubdata["all_round"] = room['all_round']
    pubdata["status"] = room['status']
    
    nsq_pub({'u':str(uid), 'b':bid, 't':'game', 'd':pubdata})
    if game_type == 'pdk':
        if stop_pop_user != str(uid):
            if last_put_user == stop_pop_user:
                put_type = "free"
            else:
                put_type = "follow"
            nsq_pub({"b":bid, "u":uid, "t":"game", "d":{"act":"turn_put", "put_type":put_type, "max_single":"n", "uid":stop_pop_user, "rid":rid, "valid_list":[], "tips_list":[], "last_put_card":last_put_card, "last_put_type":"", "last_put_point":[]}})
        else:
            user_seat = members.index(str(uid))
            last_user_seat = (user_seat - 1) % len(members)
            current_user = members[last_user_seat]
            tdh.notify_next_user(current_user)
            for member in members:
                if member != str(uid):
                    p = Player(member, bid, rid)
                    left_num = len(p.current_card.members)
                    card_warning = tdh.room['card_warning']
                    if card_warning:
                        card_warning = int(card_warning)
                    else:
                        card_warning = 1
                    if left_num <= card_warning:
                        nsq_pub({"b":bid, "u":uid, "t":"game", "d":{"act":"card_warning", "left_num":left_num, "uid":member, "rid":tdh.rid}})
                    
def get_match_base_score(bid, mid, all_round, game_round, rid):
    db = dao.Game_DB()
    #match = db.match_info(bid, mid)
    #mround = match['mround']
    #all_round = int(all_round)
    #game_round = int(game_round)
    #win_score = mround * match['score'] + all_round - game_round
    room_info = db.get_room(rid, bid)
    win_score = room_info['base_score'] + all_round - game_round + 1
    return win_score

def json_encode(data):
    return json.dumps(data, separators=(',', ':'))

def nsq_pub(message, topic='response'):
    try:
        nsq_client = nsqd.Client("http://%s/" % config.NSQ_HTTP)
        if isinstance(message, dict):
            message = json_encode(message)
        logging.info(u"推送消息:%s" % message)
        nsq_client.pub(topic, message)
        return True
    except:
        logging.error("nsq send error", exc_info=True)
        return False
    
def push_room_cast(rid, bid, uid, data):
    rid = data['rid']
    l = List(rid)
    for member in l.members:
        nsq_pub.pub({"d":data, "u":str(member), "b":bid, "t":"game"})
    return 

def push_member_cast(members, bid, uid, data):
    for member in members:
        if not member or member == str(uid):
            continue
        nsq_pub.pub({"d":data, "u":str(member), "b":bid, "t":"game"})
    return

class Player():
    def __init__(self, uid, bid='', rid='', first=False):
        self.uid = uid
        self.bid = bid
        self.rid = rid
        if first:
            redisco.connection.delete("p:%s:%s:%s:current_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:out_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:dark_bar" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:white_bar" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:pair" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:eat" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s" % (bid, uid, rid))
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
            self.score['score'] = 0
            self.score['win_score'] = 0
            self.score['put_flag'] = ''
        else:
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
        self.current_card = List("p:%s:%s:%s:current_card" % (bid, uid, rid))
        self.out_card = List("p:%s:%s:%s:out_card" % (bid, uid, rid))
        self.dark_bar = List("p:%s:%s:%s:dark_bar" % (bid, uid, rid))
        self.white_bar = List("p:%s:%s:%s:white_bar" % (bid, uid, rid))
        self.pair = List("p:%s:%s:%s:pair" % (bid, uid, rid))
        self.eat = List("p:%s:%s:%s:eat" % (bid, uid, rid))
    
    def clear(self):
        redisco.connection.delete("p:%s:%s:%s:current_card" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s:out_card" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s:dark_bar" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s:white_bar" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s:pair" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s:eat" % (self.bid, self.uid, self.rid))
        redisco.connection.delete("p:%s:%s:%s" % (self.bid, self.uid, self.rid))
        
    def get_data(self):
        return {"uid":self.uid,
                "current_card":self.current_card.members,
                "out_card":self.out_card.members,
                "dark_bar":self.dark_bar.members,
                "white_bar":self.white_bar.members,
                "pair":self.pair.members,
                "eat":self.eat.members,
                "score":self.score['score'],
                }

class MaJiangCheck():
    def __init__(self):
        self._res = []
        self.joker_list = []
    
    def all_combination(self, all_card, card, joker_list=[]):
        c_1 = card - 1
        c_2 = card - 2
        c1 = card + 1
        c2 = card + 2
        res = []
        if all_card.count(card) >= 2:
            res.append([card, card])
        if card < 40:
            j_n = len(joker_list)
            if c1 % 10 <= 8 and c2%10 <=9 and c2/10 == card/10:
                if c1 in all_card and c2 in all_card:
                    res.append([c1, c2])
                elif c1 in all_card and j_n >= 1:
                    res.append([c1, joker_list[0]])
                elif c2 in all_card and j_n >= 1:
                    res.append([c2, joker_list[0]])
            if c_1 % 10 >0 and c1 % 10 <=9 and c_1/10 == card/10 and c1/10==card/10:
                if c1 in all_card and c_1 in all_card:
                    res.append([c_1, c1])
                elif c1 in all_card and j_n >= 1:
                    res.append([c1, joker_list[0]])
                elif c_1 in all_card and j_n >= 1:
                    res.append([c_1, joker_list[0]])
            if c_1 % 10 >0 and c_2 % 10 >0 and c_2/10 == card/10 and c_1/10==card/10:
                if c1 in all_card and c_1 in all_card:
                    res.append([c_1, c_2])
                elif c1 in all_card and j_n >= 1:
                    res.append([c_1, joker_list[0]])
                elif c_1 in all_card and j_n >= 1:
                    res.append([c_2, joker_list[0]])
            
        if all_card.count(card) == 1 and len(joker_list) >= 1:
            res.append([card, joker_list[0]])
        elif len(joker_list) >= 2:
            res.append([joker_list[0], joker_list[1]])
        return res
    
    def card_group(self, all_card, pre='', joker_list=[]):
        card_list = self.trans_card(all_card)
        if not card_list:
            return self._res
        c = card_list.pop(0)
        all_group = self.all_combination(card_list, c, joker_list)
        if not all_group:
            return self.card_group(card_list, pre, joker_list)
        for group in all_group:
            tmp = pre
            card_copy = copy.deepcopy(card_list)
            joker_copy = copy.deepcopy(joker_list)
            g1 = group[0]
            g2 = group[1]
            if g1 in card_copy:
                card_copy.remove(g1)
            elif g1 in joker_copy:
                joker_copy.remove(g1)
            else:
                break
            if g2 in card_copy:
                card_copy.remove(g2)
            elif g2 in joker_copy:
                joker_copy.remove(g2)
            else:
                break
            
            tmp += "%s,%s,%s_" % (c, g1, g2)
            self._res.append(tmp)
            self.card_group(card_copy, tmp, joker_copy)
        return self._res
        
    def card_group_merge(self, all_card):
        card_list = self.trans_card(all_card)
        tmp_result = []
        for group in self._res:
            if group.endswith("_"):
                group = group[:-1]
            rows = group.split("_")
            if len(rows) > len(tmp_result):
                tmp_result = rows
        res = []
        for row in tmp_result:
            seq = []
            for x in row.split(","):
                if int(x) in card_list:
                    card_list.remove(int(x))
                seq.append(int(x))
            res.append(seq)
        self._res = []
        return res, card_list

    def trans_card(self, all_card):
        return sorted([int(x) for x in all_card])
    
    def get_jiang(self, card, joker_list=[]):
        r = []
        for k in set(card):
            if card.count(k) >= 2 or joker_list:
                r.append(k)
        r.sort()
        return r
    
    def count_group(self, all_card, jiang):
        n = 0
        res = []
        card_list = self.trans_card(all_card)
        if card_list.count(jiang) < 2:
            card_list.remove(jiang)
            if self.joker_list:
                self.joker_list.pop()
            else:
                return 0, []
        else:
            card_list.remove(jiang)
            card_list.remove(jiang)
        n += 1
        left_card = []
        card_list.sort()
        joker_list = copy.deepcopy(self.joker_list)
        self.card_group(card_list, '', joker_list)
        seq, left_card = self.card_group_merge(card_list)
        n += len(seq)
        return n, left_card
    
    def check_win(self, n, current_card, card='', joker=[]):
        if card:
            current_card.append(card)
        current_card = self.trans_card(current_card)
        joker = self.trans_card(joker)
        joker_list = []
        for j in joker:
            j_n = current_card.count(j)
            joker_list.extend([j]*j_n)
            for i in range(j_n):
                current_card.remove(j)
        jiang_list = self.get_jiang(current_card, joker_list)
        for jiang in jiang_list:
            all_joker = copy.deepcopy(joker_list)
            self.joker_list = all_joker
            allcard = self.trans_card(current_card)
            group_n, left_card = self.count_group(allcard, jiang)
            if not left_card and group_n + n >= 5:
                return True
        return False
    
class MaJiang():
    def __init__(self, rid, bid, dealer=None):
        self.rid = str(rid)
        if dealer:
            redisco.connection.delete("r:%s:current_card" % rid)
            redisco.connection.delete("r:%s:out_card" % rid)
            # redisco.connection.delete("r:%s" % rid)
            redisco.connection.delete("r:%s:mid" % rid)
            self.room = Hash("r:%s" % rid)
            self.room['dealer'] = dealer
            self.room['last_get_user'] = dealer
            self.room['last_put_user'] = ''
            #game_round = int(self.room.get('game_round', 0))
            #self.room['game_round'] = game_round + 1
            self.room['stop_pop_user'] = ''
            self.room['stop_pop_act'] = ''
        else:
            self.room = Hash("r:%s" % rid)
        self.current_card = List("r:%s:current_card" % rid)
        self.out_card = List("r:%s:out_card" % rid)
        self.bid = bid
        l = List("r:%s:p" % rid)
        self.members = l.members
    
    def incr_mid(self):
        return redisco.connection.incr("r:%s:mid" % self.rid)
    
    def start(self):
        self.room['status'] = 'start'
        w = [str(x) for x in range(11, 20)] * 4
        d = [str(x) for x in range(21, 30)] * 4
        t = [str(x) for x in range(31, 40)] * 4
        f = [str(x) for x in range(41, 48)] * 4
        random.shuffle(w)
        random.shuffle(d)
        random.shuffle(t)
        random.shuffle(f)
        player_cnt = len(self.members)
        init_left_card = 136 - player_cnt * 13 - 1
        #f = [str(x) for x in range(41, 48)]
        #f = f + sorted(f * 3)
        game_type = self.room['game_type']
        if game_type in ('zzmj', 'csmj'):
            #不带风的情况
            all_card = w + d + t
            init_left_card -= 28
        elif game_type == 'hzmj':
            self.room['joker'] = '10'
            f = ['10'] * 4
            all_card = w + d + t + f 
            init_left_card -= 24
        else:
            all_card = w + d + t + f
            
        random.shuffle(all_card)
        
        dealer_seat = self.members.index(self.room['dealer'])
        for i in range(player_cnt):
            idex = (dealer_seat + i) % player_cnt
            uid = self.members[idex]
            player = Player(uid, self.bid, self.rid, True)
            card = []
            for i in range(13):
                card.append(all_card.pop())
                card.sort()
            player.current_card.clear()
            player.current_card.extend(card)
            mid = self.incr_mid()
            nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"status":"start", "left_card":init_left_card, "rid":self.rid, "mid":mid, "act":"game_start", "dealer":self.room['dealer'], "card":card, "game_round":self.room['game_round'], "all_round":self.room['all_round']}})
        dealer = self.room['dealer']
        self.room['last_get_user'] = dealer
        self.current_card.clear()
        self.current_card.extend(all_card)
        self.next_pop(dealer)
        logging.info(u"房间rid:%s,game_round:%s,开始发牌: %s" % (self.rid, self.room['game_round'], str(self.current_card.members)))
        
    def trans_card(self, all_card):
        res = []
        for c in all_card:
            res.append(int(c))
        res.sort()
        return res
    
    def get_horse(self, num, winner):
        seat_horse_card = [['11', '15', '19', '21', '25', '29', '31', '35', '39', '41', '45'],
                           ['12', '16', '22', '26', '32', '36', '42', '46'],
                           ['13', '17', '23', '27', '33', '37', '43', '47'],
                           ['14', '18', '24', '28', '34', '38', '44'],
                           ]
        
        horse_card = []
        dealer = self.room['dealer']
        dealer_seat = self.members.index(str(dealer))
        # 庄家座位
        winner_seat = self.members.index(str(winner))
        # 赢家的座位
        if self.room['game_type'] == 'hzmj':
            winner_seat_horse = seat_horse_card[0]
        else:
            winner_seat_horse = seat_horse_card[winner_seat - dealer_seat]
        # 该赢家对应座位的马牌列表
        current_card = self.current_card.members
        jk = self.room['joker']
        if jk:
            joker_list = jk.split(",")
        else:
            joker_list = []
        all_horse_card = current_card[:num]
        for card in all_horse_card:
            if card in winner_seat_horse or card in joker_list:
                horse_card.append(card)
        logging.info(u"获取马牌:num:%s,所有马牌:%s, 已中马牌:%s,种马数量 :%s" % (num, all_horse_card, horse_card, len(horse_card)))
        return all_horse_card, horse_card
        
    def next_pop(self, uid=None, from_bar=False):
        # 发牌逻辑
        if not uid:
            last_get_user = self.room['last_get_user']
            logging.info("next_pop, last:%s" % last_get_user)
            last_player_seat = self.members.index(str(last_get_user))
            idx = (last_player_seat + 1) % len(self.members)
            uid = self.members[idx]
        
        if len(self.current_card.members) <= int(self.room['horse']):
            logging.info("over===cccccccccc========%s" % len(self.current_card.members))
            self.game_over()
            return
        card = self.current_card.pop()
        if not card:
            logging.info("over===========")
            self.game_over()
            return
        self.room['last_get_user'] = uid
        if from_bar:
            self.room['bar_get_card'] = card
        else: 
            self.room['bar_get_card'] = ''
            
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        p.current_card.append(card)
        # 判断胡牌,杠牌
        tips = []
        bar_card = []
        current_user = Hash("%s_%s" % (self.bid, uid))
        if self.room['mid'] and (current_user['online'] != 'y' or current_user['rid'] != self.rid):
            tips = []
            #离线用户不检查牌型
        else:
            if self.check_win(p, ''):
                tips.append("win")
            
            init_dark_bar = self.check_init_dark_bar(current_card)
            if self.check_bar(current_card, card):
                tips.append("dark_bar")
                bar_card.append(card)
            elif self.check_pair_bar(p.pair.members, card):
                tips.append("pair_bar")
                
            if init_dark_bar:
                tips.append("dark_bar")
                bar_card.extend(init_dark_bar)
            
        if tips:
            self.room['stop_pop_user'] = uid
            self.room['stop_pop_act'] = ",".join(tips)
        
        mid = self.incr_mid()
        left_card = len(self.current_card)
        for member in self.members:
            #if member != uid:
            #    tips = []
            data = {"b":self.bid, "u":str(member), "t":"game", "d":{"left_card":left_card, "mid":mid, "uid":uid, "act":"get_card", "card":card, "tips":tips, "bar_card":bar_card, "rid":self.rid}}
            nsq_pub(data)
        
        if not tips:
            self.notify_put(uid)
        
        if self.room['mid'] and (current_user['online'] != 'y' or current_user['rid'] != self.rid):
            self.room['stop_pop_user'] = ""
            time.sleep(0.05)
            self.put_card(uid, {"card":card})
        
    def put_card(self, uid, data):
        # 玩家出牌逻辑
        uid = str(uid)
        stop_pop_user = self.room['stop_pop_user']
        stop_pop_act = self.room['stop_pop_act']
        if stop_pop_act:
            logging.error(u"玩家:%s有提示未处理,轮不到%s出牌" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        
        if stop_pop_user and stop_pop_user != uid:
            logging.error(u"玩家:%s有提示未处理,轮不到%s出牌" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        last_get_user = self.room['last_get_user']
        if last_get_user != uid:
            logging.error(u"该玩家:%s出牌,轮不到%s出牌" % (last_get_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        last_put_user = self.room['last_put_user']
        if uid == last_put_user:
            logging.error(u"玩家:%s不能连续出牌" % (uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = data['card']
        p = Player(uid, self.bid, self.rid)
        if p.current_card.count(card) == 0:
            logging.error(u"出牌错误,该玩家没有该牌")
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        p.out_card.append(card)
        p.current_card.remove(card)
        #print uid, p.current_card.members
        self.room['last_put_user'] = uid
        self.room['last_get_user'] = uid
        # 检查别人是否胡牌下发提示
        stop_pop_card = False
        mid = self.incr_mid()
        tips = []
        game_type = self.room['game_type']
        tips_user = ''
        tips_user_tips = []
        for member in self.members:
            tip = []
            if game_type =='hzmj' and card == '10':
                win_card = []
                tips = []
            elif member != uid:
                win_card = []
                player = Player(member, self.bid, self.rid)
                current_card = player.current_card.members
                tips = [] 
                #比赛用户离线不做提示
                if self.room['mid']:
                    member_info = Hash("%s_%s" % (self.bid, member))
                    if member_info['online'] != 'y' or member_info['rid'] != self.rid:
                        tips = []
                    else:
                        if self.check_bar(current_card, card):
                            tips.append("bar")
                            tips.append("pair")
                        elif self.check_pair(current_card, card):
                            tips.append("pair")
                else:
                    if self.check_bar(current_card, card):
                        tips.append("bar")
                        tips.append("pair")
                    elif self.check_pair(current_card, card):
                        tips.append("pair")
                
                if tips:
                    stop_pop_card = True
                    tips_user = member
                    tips_user_tips = tips
                    self.room['stop_pop_user'] = member
                    self.room['stop_pop_act'] = ",".join(tips)
            else:
                tips = []
                win_card = self.check_win_card(p, [])
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"win_card":win_card, "mid":mid, "act":"put_card", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
            
        if tips_user:
            mid = self.incr_mid()
            nsq_pub({"b":self.bid, "u":tips_user, "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips_user_tips, "rid":self.rid, "uid":tips_user, "eat_card":[]}})
            return
        
        if not stop_pop_card:
            self.room['stop_pop_user'] = ""
            self.next_pop()

    def pass_card(self, uid, data):
        logging.info("pass:%s" % uid)
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        stop_pop_act = self.room['stop_pop_act']
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        last_get_user = self.room['last_get_user']
        if "bar_win" in stop_pop_act:
            self.next_pop(last_get_user, True)
        else:
            if last_get_user != uid:
                self.next_pop()
            else:
                self.notify_put(uid)
            
    def notify_put(self, uid):
        '''通知玩家出牌'''
        #self.room['last_get_user'] = uid
        #self.room['stop_pop_user'] = ""
        #self.room['stop_pop_act'] = ""
        return
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"turn_put", "rid":self.rid, "uid":uid}})
            
    def get_joker_cnt(self, card, joker):
        joker_cnt = 0
        for j in joker:
            k = card.count(j)
            joker_cnt += k
        return joker_cnt
    
    def get_jiang(self, card):
        r = []
        for k in set(card):
            if card.count(k) >= 2:
                r.append(k)
        return r

    def get_n(self, all_card, jiang='', joker=[]):
        n = 0
        # print "===当将牌为%s时,各种排列组合为==" % jiang
        res = []
        left_res = []
        if jiang:
            jiang = int(jiang)
        card = self.trans_card(all_card)
        card.sort()
        if jiang and card.count(jiang) >= 2:
            card.remove(jiang)
            card.remove(jiang)
            n += 1
        while card:
            c = card.pop(0)
            if card.count(c) >= 2:
                n += 1
                card.remove(c)
                card.remove(c)
                res.append([c, c, c])
            elif c > 40:
                left_res.append(c)
            else:
                c2 = c + 1
                c3 = c + 2
                if c2 in card and c3 in card:
                    card.remove(c2)
                    card.remove(c3)
                    res.append([c, c2, c3])
                    n += 1
                else:
                    left_res.append(c)

        win_card = []
        if len(left_res) == 1:
            win_card = left_res
            c1 = left_res[0]
            if c1%10 >= 4:
                if c1%10 >= 7:
                    if [c1-6, c1-5, c1-4] in res and [c1-3, c1-2, c1-1] in res:
                        win_card.extend([c1-6, c1-3, c1])
                    
                if [c1-3, c1-2, c1-1] in res:
                    win_card.extend([c1-3, c1])
                elif [c1+1, c1+1, c1+1] in res:
                    win_card.extend([c1-1, c1, c1+2])
                elif [c1+2, c1+2, c1+2] in res:
                    win_card.extend([c1, c1+1])
                elif [c1-1, c1-1, c1-1] in res:
                    win_card.extend([c1-2, c1, c1+1])
                elif [c1-2, c1-2, c1-2] in res:
                    win_card.extend([c1-1, c1])
            else:
                if [c1+1, c1+2, c1+3] in res:
                    win_card.extend([c1, c1+3])
        elif len(left_res) == 2:
            left_res.sort()
            c1 = left_res[0]
            c2 = left_res[1]
            if c2 - c1 == 0:
                win_card = [c1]
            elif c2 - c1 == 1:
                if c2 < 40:
                    if str(c2)[-1] == '9':
                        win_card = [c1-1]
                    elif str(c1)[-1] == '1':
                        win_card = [c2+1]
                    else:
                        if [c1-3, c1-2, c1-1] in res:
                            win_card = [c1-4, c1-1, c2+1]
                        else: 
                            win_card = [c1-1, c2+1]
            elif c2 - c1 == 2:
                win_card = [c1+1]
        return n, list(set(win_card))

    def check_win(self, player, card='', joker=[]):
        '''检查是否符合糊'''
        # 检查
        n = 0
        dark_bar = player.dark_bar.members
        white_bar = player.white_bar.members
        pair = player.pair.members
        #eat = player.eat.members
        n += len(dark_bar)
        n += len(white_bar)
        n += len(pair)
        #n += len(eat)
        current_card = player.current_card.members
        if card:
            current_card.append(card)
        
        if n == 0 and self.room['seven_pair_win'] == 'y':
            if self.check_seven_pairs(current_card, []):
                return True
            
        jiang_list = self.get_jiang(current_card)
        res = [0,]
        for jiang in jiang_list:
            allcard = self.trans_card(current_card)
            win_n, win_card = self.get_n(allcard, jiang)
            res.append(win_n)
        if max(res)+n >= 5:
            return True
        return False

    def check_win_card_old(self, player, joker=[]):
        # 检查
        n = 0
        dark_bar = player.dark_bar.members
        white_bar = player.white_bar.members
        pair = player.pair.members
        #eat = player.eat.members
        n += len(dark_bar)
        n += len(white_bar)
        n += len(pair)
        #n += len(eat)
        current_card = player.current_card.members
        jiang_list = self.get_jiang(current_card)
        res = []
        if jiang_list:
            for jiang in jiang_list:
                card = self.trans_card(current_card)
                win_n, win_card = self.get_n(card, jiang)
                if win_n == 4-n and win_card:
                    res.extend(win_card)
        card = self.trans_card(current_card)
        win_n, win_card = self.get_n(card, '')
        if win_n == 4-n and win_card:
            res.extend(win_card)
        return [str(x) for x in set(res)]

    def check_win_card(self, player, joker=[]):
        w = [str(x) for x in range(11, 20)]
        d = [str(x) for x in range(21, 30)]
        t = [str(x) for x in range(31, 40)]
        f = [str(x) for x in range(41, 48)]
        all_card = w + d + t
        if self.room['game_type'] == 'gdmj':
            all_card += f
        win_card = []
        for card in all_card:
            if self.check_win(player, card):
                win_card.append(card)
        return win_card
    
    def get_max_n(self, card_str, joker_list=[]):
        #allcard = [int(x) for x in card_str]
        #ccc = [int(x) for x in card_str]
        #joker = [int(x) for x in joker]
        allcard = []
        for x in card_str:
            allcard.append(int(x))
        ccc = []
        for x in card_str:
            ccc.append(int(x))
        joker = []
        for x in joker_list:
            joker.append(int(x))
        
        joker_cnt = self.get_joker_cnt(allcard, joker)
        if joker_cnt >= 4:
            #4张鬼牌可直接胡
            return 5
        jiang_list = self.get_jiang(allcard, joker)
        if not jiang_list:
            return 0
        #print jiang_list, '可以做将的列表'
        res = [0, ]
        for jiang in sorted(jiang_list):
            ddd = sorted(ccc)
            n, rs, left_res, win_card = self.get_n(ddd, jiang, joker)
            res.append(n)
        return max(res) + 1

    def get_win_card(self, card_str, joker_list=[], left_n=4):
        '''计算胡牌的可能性'''
        allcard = []
        for x in card_str:
            allcard.append(int(x))
        ccc = []
        for x in card_str:
            ccc.append(int(x))
        joker = []
        for x in joker_list:
            joker.append(int(x))
        jiang_list = self.get_jiang(allcard, joker)
        res = []
        if jiang_list:
            for jiang in sorted(jiang_list):
                ddd = sorted(ccc)
                n, rs, left_res, win_card = self.get_n(ddd, jiang, joker)
                n += 1
                if n == left_n:
                    res.extend(win_card)
        else:
            n, rs, left_res, win_card = self.get_n(allcard, '', joker)
            if n == left_n:
                res.extend(win_card)
        return sorted([str(x) for x in set(res)])
    
    def get_seven_pairs(self, all_card, joker=[]):
        jiang_list = []
        joker_cnt = 0
        card = self.trans_card(all_card)
        joker_list = self.trans_card(joker)
        for j in joker_list:
            m = card.count(j)
            joker_cnt += m
            for i in range(m):
                card.remove(j)
        for c in set(card):
            if card.count(c) >= 2:
                jiang_list.append(c)
                for i in range(2):
                    card.remove(c)
        if not jiang_list:
            return 0
        return len(jiang_list) + joker_cnt
    
    def check_seven_pairs(self, all_card, joker_list=[]):
        '''七对胡'''
        pair_num = self.get_seven_pairs(all_card, joker_list)
        return pair_num == 7
    
    def check_thirteen_orphans(self, all_card):
        '''十三幺'''
        jiang_list = self.get_jiang(all_card)
        if len(jiang_list) != 1:
            return False
        jiang = jiang_list[0]
        card_list = ['11', '19', '21', '29', '31', '39', '41', '42', '43', '44', '45', '46', '47']
        if set(all_card) == set(card_list) and jiang in card_list:
            return True
        return False
    
    def check_init_dark_bar(self, current_card):
        # 检查初始手牌能否暗杠
        res = []
        for k in set(current_card):
            if current_card.count(k) == 4:
                res.append(k)
        return res
    
    def check_dark_bar(self, current_card, card=''):
        # 检查摸的牌能否暗杠
        if current_card.count(card) == 4:
            return True
        return False

    def check_bar(self, current_card, card=''):
        # 检查能否杠
        if current_card.count(card) == 3:
            return True
        return False

    def check_pair_bar(self, pair, card=''):
        # 检查碰过的牌是否摸到杠
        if pair.count(card) >= 1:
            return True
        return False
    
    def check_pair(self, current_card, card=''):
        # 检查能否碰牌
        if current_card.count(card) >= 2:
            return True
        return False
    
    def dark_bar(self, uid, data):
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = data.get('card','')
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        if not card:
            for k in set(current_card):
                if current_card.count(k) == 4:
                    card = k
                    
        if not self.check_dark_bar(current_card, card):
            logging.error(u"请求错误,该用户不能杠牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        p.current_card.remove(card, 4)
        p.dark_bar.append(card)
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        member_len = len(self.members)
        match_id = self.room['mid']
        if match_id:
            bar_score = 0
            every_lose_score = 0
        else:
            bar_score = (member_len - 1) * 2
            every_lose_score = 2
        mid = self.incr_mid()
        for member in self.members:
            if not match_id:
                if member == uid:
                    p.score['score'] = int(p.score['score']) + bar_score
                    logging.info(u"用户%s暗杠得%s分" % (uid, bar_score))
                else:
                    player = Player(member, self.bid, self.rid)
                    player.score['score'] = int(player.score['score']) - every_lose_score
                    logging.info(u"用户%s暗杠,%s扣%s分:%s" % (uid, member, every_lose_score, player.score['score']))
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"dark_bar", "card":card, "tips":[], "rid":self.rid, "uid":uid}})
        self.next_pop(uid)

    def pair_bar(self, uid, data):
        # 碰过别的牌, 然后自己摸到一张
        # card = data['card']
        stop_pop_user = self.room['stop_pop_user']
        if stop_pop_user and stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        p = Player(uid, self.bid, self.rid)
        card = p.current_card.members[-1]
        if not self.check_pair_bar(p.pair.members, card):
            logging.error(u"请求错误,该用户不能杠牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        p.current_card.remove(card)
        p.pair.remove(card)
        p.white_bar.append(card)
        stop_pop_card = False
        self.room['last_get_user'] = uid
        match_id = self.room['mid']
        if not match_id:
            member_len = len(self.members)
            bar_score = (member_len - 1)
            p.score['score'] = int(p.score['score']) + bar_score
            logging.info(u"用户%s明杠得%s分" % (uid, bar_score))
        mid = self.incr_mid()
        tips_user = ''
        tips = []
        user_seat = self.members.index(uid)
        player_cnt = len(self.members)
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = self.members[idex]
            tips = []
            if member != uid:
                player = Player(member, self.bid, self.rid)
                # 玩家有杠个扣1分
                if not match_id:
                    player.score['score'] = int(player.score['score']) - 1
                    logging.info(u"用户%s明杠,玩家%s各扣1分:%s" % (uid, member, player.score['score']))
                if tips_user:
                    pass
                else:
                    if self.room['grab_bar_win'] == 'y':
                        if self.check_win(player, card):
                            tips = ["pair_bar_win"]
                            stop_pop_card = True
                            tips_user = member
                            self.room['stop_pop_user'] = member
                            self.room['stop_pop_act'] = ",".join(tips)
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"pair_bar", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
        
        if not stop_pop_card:
            # 有抢杠胡的玩家,需要停止发牌  
            self.next_pop(uid, from_bar=True)
        
    def bar(self, uid, data):
        # 自己有三张,直接杠别人出的牌
        # card = data['card']
        # bar_uid = data['put_card_uid']
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        
        card = last_put_player.out_card.members[-1]
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        if not self.check_bar(current_card, card):
            logging.error(u"请求错误,该用户不能杠牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = last_put_player.out_card.pop()
        p.current_card.remove(card, 3)
        p.white_bar.append(card)
        
        self.room['last_get_user'] = uid
        match_id = self.room['mid'] 
        member_len = len(self.members)
        if not match_id:
            bar_score = member_len - 1
            p.score['score'] = int(p.score['score']) + bar_score
            logging.info(u"用户%s杠得3分:%s" % (uid, p.score['score']))
        mid = self.incr_mid()
        stop_pop_card = False
        tips_user = ''
        tips = []
        user_seat = self.members.index(uid)
        player_cnt = len(self.members)
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = self.members[idex]
            tips = []
            if member != uid:
                player = Player(member, self.bid, self.rid)
                # 玩家有杠个扣1分
                if member == last_put_user:
                    bar_score = member_len - 1
                    player.score['score'] = int(player.score['score']) - bar_score
                    logging.info(u"用户%s点杠,扣%s分:%s" % (member, bar_score, player.score['score']))
                if tips_user:
                    pass
                else:
                    if self.room['grab_bar_win'] == 'y':
                        if self.check_win(player, card):
                            tips = ["pair_bar_win"]
                            stop_pop_card = True
                            tips_user = member
                            self.room['stop_pop_user'] = member
                            self.room['stop_pop_act'] = "bar_win"
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"bar", "card":card, "tips":tips, "rid":self.rid, "uid":uid, "put_card_uid":last_put_user}})
            
        if not stop_pop_card:
            self.room['stop_pop_user'] = ""
            self.room['stop_pop_act'] = ""
            self.next_pop(uid, from_bar=True)
    
    def pair(self, uid, data):
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        # card = data['card']
        # put_card_uid = data['put_card_uid']
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        card = last_put_player.out_card.members[-1]
        
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        if not self.check_pair(current_card, card):
            logging.info(u"请求错误,该用户不能碰牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = last_put_player.out_card.pop()
        
        p.current_card.remove(card, 2)
        p.pair.append(card)
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"pair", "card":card, "tips":[], "rid":self.rid, "uid":uid, "put_card_uid":last_put_user}})
        # p = Player(self.room['lasy_player'], self.bid, self.rid)
        # p.out_card.remove(card, -1)
        self.room['last_get_user'] = uid
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        self.notify_put(uid)
        
    def win(self, uid, data):
        if self.room['status'] != 'start':
            logging.error(u"该轮游戏已结束")
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        # card = data.get('card', '')
        
        p = Player(uid, self.bid, self.rid)
        card = p.current_card.members[-1]
        # if not self.check_win(p, card):
        if not self.check_win(p, ''):
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        all_horse_card = []
        horse_card = []
        horse_num = 0
        horse = self.room['horse']
        if horse:
            horse = int(horse)
            all_horse_card, horse_card = self.get_horse(horse, uid)
            horse_num = len(horse_card)
            
        member_len = len(self.members)
        match_id = self.room['mid']
        if match_id:
            #比赛杠没有分
            all_round = int(self.room['all_round'])
            game_round = int(self.room['game_round'])
            base_score = get_match_base_score(self.bid, match_id, all_round, game_round, self.rid)
        else:
            base_score = 1
        every_lose_score = 2 * base_score * (1 + horse_num)
        win_score = every_lose_score * (member_len - 1)
        
        if self.room['bar_get_card'] == card and self.room['bar_win_duty'] == 'y':
            # 杠上开花,杠爆全包
            last_put_user = self.room['last_put_user']
            p.score['score'] = int(p.score['score']) + win_score
            last_put_player = Player(last_put_user, self.bid, self.rid)
            last_put_player.score['score'] = int(last_put_player.score['score']) - win_score
            logging.info(u"用户%s杠上开花得%s分,点杠者%s全包" % (uid, win_score, last_put_user))
        else:
            p.score['score'] = int(p.score['score']) + win_score
            logging.info(u"用户%s自摸胡牌,中%s马,得%s分" % (uid, horse_num, win_score))
            for member in self.members:
                if member != uid:
                    player = Player(member, self.bid, self.rid)
                    player.score['score'] = int(player.score['score']) - every_lose_score
                    logging.info(u"用户%s自摸胡牌,中%s马,玩家各扣%s分" % (uid, horse_num, every_lose_score))
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "card":card, "tips":[], "rid":self.rid, "uid":uid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}})
        self.game_over(uid, card, all_horse_card, horse_card, horse_num, False, "win", [u"自模胡",])

    def pair_bar_win(self, uid, data):
        # 抢杠胡,杠家全包,退还之前杠的分数
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        #card = data['card']
        bar_uid = self.room['last_get_user']
        last_put_uid = self.room['last_put_user']
        bar_player = Player(bar_uid, self.bid, self.rid)
        white_bar_member = bar_player.white_bar.members
        if white_bar_member:
            card = white_bar_member[-1]
        else:
            card = data.get("card", "")
        
        p = Player(uid, self.bid, self.rid)
        if not self.check_win(p, card):
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        bar_win_type = self.room['stop_pop_act']
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        all_horse_card = []
        horse_card = []
        horse_num = 0
        horse = self.room['horse']
        if horse:
            horse = int(horse)
            all_horse_card, horse_card = self.get_horse(horse, uid)
            horse_num = len(horse_card)
        
        member_len = len(self.members)
        match_id = self.room['mid']
        if match_id:
            #比赛杠没有分
            bar_score = 0
            deduct_bar_score = 0
            all_round = int(self.room['all_round'])
            game_round = int(self.room['game_round'])
            base_score = get_match_base_score(self.bid, match_id, all_round, game_round, self.rid)
        else:
            if bar_win_type == "pair_bar_win":
                bar_score = 1
            else:
                bar_score = 0
            deduct_bar_score = member_len - 1
            base_score = 1
            
        every_lose_score = 2 * base_score * (1 + horse_num)
        win_score = every_lose_score * (member_len - 1)
        logging.info(u"用户%s抢杠胡,中%s马,得%s分" % (uid, horse_num, win_score))
        
        p.score['score'] = int(p.score['score']) + win_score + bar_score
        mid = self.incr_mid()
        for member in self.members:
            if member != uid:
                # 抢杠胡全包
                player = Player(member, self.bid, self.rid)
                if member == bar_uid:
                    player.pair.append(card)
                    player.white_bar.remove(card)
                    player.score['score'] = int(player.score['score']) - deduct_bar_score - win_score
                    logging.info(u"用户%s抢杠胡,中%s马,抢杠全包:%s, 扣%s分" % (uid, horse_num, bar_uid, win_score))
                else:
                    if bar_win_type == "bar_win" and member == last_put_uid:
                        player.score['score'] = int(player.score['score']) + deduct_bar_score
                    else:
                        player.score['score'] = int(player.score['score']) + bar_score
                        logging.info(u"用户%s抢杠胡,中%s马,抢杠全包,玩家退还杠扣的1分:%s" % (uid, horse_num, member))
                    
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "card":card, "tips":[], "rid":self.rid, "uid":uid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}})
        self.game_over(uid, card, all_horse_card, horse_card, horse_num, False, "pair_bar_win",  [u"抢杠胡",])
        
    def game_over(self, winner='', card='', all_horse_card=[], horse_card=[], horse_num=0, from_dissmiss=False, win_type="", win_type_list=[]):
        time.sleep(0.05)
        if from_dissmiss:
            from_dissmiss = "y"
        else:
            from_dissmiss = "n"
        
        db = dao.Game_DB()
        rules = {}
        #room_info = db.get_room(self.rid, self.bid)
        #gid = room_info.get("gid")
        gid = self.room['gid']
        if gid:
            rows = db.game_rule(gid)
        else:
            rows = db.room_rule(self.rid)
            gid = ""
        for row in rows:
            k = row['param']
            v = row['value']
            rules[k] = v
        
        #比赛的牌局统一规则
        match_id = self.room['mid']
        if match_id:
            rules = {"horse":0, "grab_bar_win":"y", "grab_bar_duty":"y", "bar_win_duty":"n", "seven_pair_win":"y"}
        else:
            match_id = ""
        game_round = self.room['game_round']
        if not game_round:
            game_round = 1
        game_round = int(game_round)
        dealer = self.room['dealer']
        player_card = []
        for uid in self.members:
            if not uid:
                continue
            p = Player(uid, self.bid, self.rid)
            p_data = p.get_data()
            
            eat_list = []
            eat_data_list = p_data['eat']
            if eat_data_list:
                for eat_data in eat_data_list:
                    eat_list.append(eat_data.split(","))
                p_data['eat'] = eat_list
            
            del p_data['out_card']
            if dealer == uid:
                is_dealer = "y"
            else:
                is_dealer = "n"
            p_data['is_dealer'] = is_dealer
            player_card.append(p_data)
            
            # 重置玩家状态,和计算分数
            if not winner:
                score = 0
                p.score['score'] = 0
                p_data['score'] = "0"
            else:
                score = int(p_data['score'])
            db.update_player(self.rid, uid, score, 0)
            db.commit()
            player_info = db.get_player(self.rid, uid)
            p_data['user_score'] = player_info['score']
            
            if uid == winner:
                is_win = 1
                horse = horse_num
            else:
                is_win = 0
                horse = 0
            dark_bar = p_data['dark_bar']
            white_bar = p_data['white_bar']
            db.add_mj_room_log(match_id, gid, self.rid, game_round, uid, score, len(white_bar), len(dark_bar), horse, is_dealer, is_win, 0, '')
            db.commit()
        game_type = self.room['game_type']
        mid = self.incr_mid()
        all_room_card = self.current_card.members
        horse = self.room['horse']
        if horse:
            left_card_num = len(all_room_card) - int(horse)
            room_left_card = all_room_card[-left_card_num:]
        else:
            room_left_card = all_room_card
        for uid in self.members:
            if not uid:
                continue
            pub_data = {"b":self.bid, "u":str(uid), "t":"game", "d":{"win_type_list":win_type_list, "room_left_card":room_left_card, "match_id":match_id, "gid":gid, "rules":rules, "win_type":win_type,"from_dissmiss":from_dissmiss,"dealer":self.room['dealer'], "game_round":self.room['game_round'], "player_card":player_card, "mid":mid, "act":"game_over", "winner":winner, "card":card, "rid":self.rid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}}
            nsq_pub(pub_data)
            db.save_game_over(self.rid, game_round, "game_over", uid, urllib.quote(json_encode(pub_data).encode("utf-8")))
            db.commit()
            try:
                if winner == uid:
                    win_round = 1
                else:
                    win_round = 0
                if db.has_user_stat(self.bid, uid, game_type):
                    db.update_user_stat(self.bid, uid, game_type, win_round)
                else:
                    db.add_user_stat(self.bid, uid, game_type, win_round, 0)
            except:
                logging.error(u"统计用户生涯错误:%s" % uid, exc_info=True)
        logging.info("game over")
        if winner:
            self.room['dealer'] = winner
        
        self.room['status'] = 'over'
        self.room['stop_pop_user'] = ''
        self.room['last_put_user'] = ''
        self.room['last_get_user'] = ''
        
        all_round = int(self.room['all_round'])
        db.game_over(self.rid, game_round)
        db.commit()
        if match_id:
            nsq_pub({"b":self.bid, "u":"", "t":"game", "d":{"all_round":all_round, "match_id":match_id, "rules":rules, "win_type":win_type,"from_dissmiss":from_dissmiss,"dealer":self.room['dealer'], "game_round":self.room['game_round'], "player_card":player_card, "mid":mid, "act":"game_over", "winner":winner, "card":card, "rid":self.rid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}}, "match_club")
        self.room['game_round'] = game_round + 1
        if all_round <= game_round:
            self.dismiss(act='room_over')
        else:
            if match_id:
                exp_time = (datetime.datetime.now() + datetime.timedelta(seconds=5)).strftime("%Y-%m-%d %H:%M:%S")
                db.add_cron(self.bid, "auto_ready", self.rid, 0, exp_time)
                db.commit()
        
    def dismiss(self, act='room_over'):
        #time.sleep(0.5)
        db = dao.Game_DB()
        player_data = {}
        player_stat = []
        if not self.room['status']:
            logging.error(u"房间结束,未开始:%s" % self.rid)
            deduct_flag = False
            winner = ""
            for uid in self.members:
                player_stat.append({"uid":uid,"horse":0,"dark_bar":0,"white_bar":0,"score":0,"win_num":0})
        else:
            p_stat = db.player_stat(self.rid)
            #logging.info(p_stat)
            for ps in p_stat:
                ps['horse'] = int(ps['horse'])
                ps['dark_bar'] = int(ps['dark_bar'])
                ps['white_bar'] = int(ps['white_bar'])
                ps['score'] = int(ps['score'])
                ps['win_num'] = int(ps['win_num'])
                player_data[str(ps['uid'])] = ps
            deduct_flag = True
            if p_stat:
                winner = p_stat[-1]['uid']
            else:
                winner = ""
            # 排序最后一家为大赢家
            player_stat = p_stat
        
        match_id = self.room['mid']
        if not match_id:
            match_id = 0
        gid = self.room['gid']
        if not gid:
            gid = 0
        else:
            for ps in player_stat:
                if ps['uid'] == winner:
                    is_winner = 'y'
                else:
                    is_winner = 'n'
                db.add_room_stat(match_id, gid, self.rid, ps['uid'], ps['score'], is_winner)
                db.commit()
            
        room_info = db.get_room(self.rid, self.bid)
        admin = room_info['admin']
        
        if not match_id:
            #比赛的房间不发送room_over
            for uid in self.members:
                if not uid:
                    continue
                pub_data = {"b":self.bid, "u":str(uid), "t":"game", "d":{"act":"room_over", "rid":self.rid, "player_stat":player_stat, "winner":winner, "admin":admin}}
                nsq_pub(pub_data)
                db.save_game_over(self.rid, 0, "room_over", uid, json_encode(pub_data))
                db.commit()
        else:
            #比赛房间不扣房卡
            deduct_flag = False
        db.dismiss_room(self.rid)
        db.commit()
        game_type = self.room['game_type']
        gid = self.room['gid']
        if match_id or gid:
            nsq_pub({"b":self.bid, "u":"", "t":"game", "d":{"game_type":game_type, "match_id":match_id, "gid":gid, "act":"room_over", "rid":self.rid, "player_stat":player_stat, "winner":winner, "admin":admin}}, "match_club")
            
        #if deduct_flag:
        #    card = room_info['card']
        #    db.deduct_card(self.bid, admin, card)
        #    nsq_pub({"act":"deduct_card", "bid":self.bid, "uid":admin, "card":card, "rid":self.rid}, "total")
        #    logging.info(u"房间%s解散成功,扣除房卡, bid:%s,uid:%s,card:%s" % (self.rid, self.bid, admin, card))
        #else:
        #    logging.info(u"房间%s解散成功,游戏无需扣房卡" % self.rid)
        for member in self.members:
            member_player = Player(member, self.bid, self.rid)
            member_player.clear()
        redisco.connection.delete("r:%s:current_card" % self.rid)
        redisco.connection.delete("r:%s:out_card" % self.rid)
        redisco.connection.delete("r:%s" % self.rid)
        redisco.connection.delete("r:%s:mid" % self.rid)
        redisco.connection.delete("r:%s:p" % self.rid)


class ZZMaJiang(MaJiang):
    def start(self):
        self.room['status'] = 'start'
        w = [str(x) for x in range(11, 20)] * 4
        d = [str(x) for x in range(21, 30)] * 4
        t = [str(x) for x in range(31, 40)] * 4
        f = [str(x) for x in range(41, 48)] * 4
        random.shuffle(w)
        random.shuffle(d)
        random.shuffle(t)
        random.shuffle(f)
        player_cnt = len(self.members)
        init_left_card = 136 - player_cnt * 13 - 1
        all_card = w + d + t
        init_left_card -= 28
        random.shuffle(all_card)
        game_round = int(self.room['game_round'])
        match_id = self.room['mid']
        members = self.members
        if match_id:
            dealer = members[game_round%player_cnt-1]
            self.room['dealer'] = dealer
        else:
            dealer = self.room['dealer']
        dealer_seat = self.members.index(self.room['dealer'])
        for i in range(player_cnt):
            idex = (dealer_seat + i) % player_cnt
            uid = self.members[idex]
            player = Player(uid, self.bid, self.rid, True)
            card = []
            for i in range(13):
                card.append(all_card.pop())
                card.sort()
            player.current_card.clear()
            player.current_card.extend(card)
            mid = self.incr_mid()
            nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"status":"start", "left_card":init_left_card, "rid":self.rid, "mid":mid, "act":"game_start", "dealer":self.room['dealer'], "card":card, "game_round":self.room['game_round'], "all_round":self.room['all_round']}})
        #dealer = self.room['dealer']
        self.room['last_get_user'] = dealer
        self.current_card.clear()
        self.current_card.extend(all_card)
        logging.info(u"转转麻将房间rid:%s,game_round:%s,开始发牌: %s" % (self.rid, self.room['game_round'], str(self.current_card.members)))
        self.next_pop(dealer)

    def next_pop(self, uid=None, from_bar=False):
        # 发牌逻辑
        if not uid:
            last_get_user = self.room['last_get_user']
            logging.info("next_pop, last:%s" % last_get_user)
            last_player_seat = self.members.index(str(last_get_user))
            idx = (last_player_seat + 1) % len(self.members)
            uid = self.members[idx]
        
        if len(self.current_card.members) <= int(self.room['horse']):
            logging.info("over===cccccccccc========%s" % len(self.current_card.members))
            self.game_over()
            return
        card = self.current_card.pop()
        if not card:
            logging.info("over===========")
            self.game_over()
            return
        self.room['last_get_user'] = uid
        if from_bar:
            self.room['bar_get_card'] = card
        else: 
            self.room['bar_get_card'] = ''
            
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        p.current_card.append(card)
        
        #检查漏胡标记, 摸牌后清除状态
        p_flag = p.score['flag']
        if p_flag == 'n':
            p.score['flag'] = ''
            
        # 判断胡牌,杠牌
        tips = []
        bar_card = []
        current_user = Hash("%s_%s" % (self.bid, uid))
        if self.room['mid'] and (current_user['online'] != 'y' or current_user['rid'] != self.rid):
            tips = []
            #离线用户不检查牌型
        else:
            if self.check_win(p, ''):
                tips.append("win")
            
            init_dark_bar = self.check_init_dark_bar(current_card)
            if self.check_bar(current_card, card):
                tips.append("dark_bar")
                bar_card.append(card)
            elif self.check_pair_bar(p.pair.members, card):
                tips.append("pair_bar")
                
            if init_dark_bar:
                tips.append("dark_bar")
                bar_card.extend(init_dark_bar)
            
        if tips:
            self.room['stop_pop_user'] = uid
            self.room['stop_pop_act'] = ",".join(tips)
        
        mid = self.incr_mid()
        left_card = len(self.current_card)
        for member in self.members:
            #if member != uid:
            #    tips = []
            data = {"b":self.bid, "u":str(member), "t":"game", "d":{"left_card":left_card, "mid":mid, "uid":uid, "act":"get_card", "card":card, "tips":tips, "bar_card":bar_card, "rid":self.rid}}
            nsq_pub(data)
        
        if not tips:
            self.notify_put(uid)
        
        if self.room['mid'] and (current_user['online'] != 'y' or current_user['rid'] != self.rid):
            self.room['stop_pop_user'] = ""
            time.sleep(0.5)
            self.put_card(uid, {"card":card})
            
    def put_card(self, uid, data, from_pass=False, repeat_user=[]):
        # 玩家出牌逻辑
        repeat = "n"
        uid = str(uid)
        #是否重复发牌给客户端
        stop_pop_user = self.room['stop_pop_user']
        if stop_pop_user and stop_pop_user != uid:
            logging.error(u"玩家:%s有提示未处理,轮不到%s出牌" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        last_get_user = self.room['last_get_user']
        if last_get_user != uid:
            logging.error(u"该玩家:%s出牌,轮不到%s出牌" % (last_get_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        last_put_user = self.room['last_put_user']
        if uid == last_put_user:
            logging.error(u"玩家:%s不能连续出牌" % (uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = data['card']
        p = Player(uid, self.bid, self.rid)
        if p.current_card.count(card) == 0:
            logging.error(u"出牌错误,该玩家%s没有该牌" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        p.out_card.append(card)
        p.current_card.remove(card)
        self.room['last_put_user'] = uid
        #self.room['last_get_user'] = uid
        
        #按照玩家座位顺序检查是否有胡牌可能
        members = self.members
        
        mid = self.incr_mid()
        for member in members:
            if member != uid:
                win_card = []
            else:
                win_card = self.check_win_card(p, [])
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"put_card", "repeat":"n", "mid":mid, "card":card, "tips":[], "rid":self.rid, "uid":uid, "win_card":win_card}})
        
        put_win_user = []
        user_seat = members.index(uid)
        player_cnt = len(members)
        tips = []
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = self.members[idex]
            if member != uid:
                member_info = Hash("%s_%s" % (self.bid, member))
                if self.room['mid'] and (member_info['online'] != 'y' or member_info['rid'] != self.rid):
                    tips = []
                else:
                    member_player = Player(member, self.bid, self.rid)
                    if member_player.score['flag'] != 'n':
                        if self.check_win(member_player, card):
                            put_win_user.append(member)
                    else:
                        logging.info(u"转转%s房间玩家%s漏胡,下一圈才可以检查是否胡" % (self.rid, member))
        if put_win_user:
            #点炮胡的情况
            self.room['stop_pop_user'] = ",".join(put_win_user)
            self.room['stop_pop_act'] = "put_win"
            tips = ["put_win"]
            mid = self.incr_mid()
            nsq_pub({"b":self.bid, "u":str(put_win_user[0]), "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
            return
        stop_pop_card = False
        tips = []
        #game_type = self.room['game_type']
        
        mid = self.incr_mid()
        for member in members:
            if member != uid:
                win_card = []
                member_info = Hash("%s_%s" % (self.bid, member))
                if self.room['mid'] and (member_info['online'] != 'y' or member_info['rid'] != self.rid):
                    tips = []
                else:
                    player = Player(member, self.bid, self.rid)
                    current_card = player.current_card.members
                    tips = [] 
                    if self.check_bar(current_card, card):
                        tips.append("bar")
                        tips.append("pair")
                    elif self.check_pair(current_card, card):
                        tips.append("pair")
                if tips:
                    stop_pop_card = True
                    self.room['stop_pop_user'] = member
                    self.room['stop_pop_act'] = ",".join(tips)
                    nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
                    
        if not stop_pop_card:
            self.next_pop()

    def check_pair_bar_tips(self, last_put_user='', card=''):
        if not last_put_user:
            last_put_user = self.room['last_put_user']
            last_put_player = Player(last_put_user, self.bid, self.rid)
            card = last_put_player.out_card.members[-1]
        
        members = self.members
        user_seat = members.index(last_put_user)
        next_idex = (user_seat + 1) % len(members)
        next_member = members[next_idex]
        tips_user = ''
        eat_card_list = []
        for member in members:
            if member != last_put_user:
                member_info = Hash("%s_%s" % (self.bid, member))
                if self.room['mid'] and (member_info['online'] != 'y' or member_info['rid'] != self.rid):
                    tips = []
                else:
                    player = Player(member, self.bid, self.rid)
                    current_card = player.current_card.members
                    tips = [] 
                    if self.check_bar(current_card, card):
                        tips.append("bar")
                        tips.append("pair")
                    elif self.check_pair(current_card, card):
                        tips.append("pair")
                    eat_card_list = []
                            
                if tips:
                    tips_user = member
                    self.room['stop_pop_user'] = member
                    self.room['stop_pop_act'] = ",".join(tips)
                    mid = self.incr_mid()
                    if tips_user:
                        nsq_pub({"b":self.bid, "u":tips_user, "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":tips_user, "eat_card":eat_card_list}})
                        return tips_user
        return False
    
    def pass_card(self, uid, data):
        logging.info("pass:%s" % uid)
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif uid not in stop_pop_user.split(","):
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        stop_pop_act = self.room['stop_pop_act']
        if "put_win" in stop_pop_act:
            player = Player(uid, self.bid, self.rid)
            player.score['flag'] = 'n'
            logging.info(u"用户胡牌点击取消执行漏胡%s" % uid)
            last_put_user = self.room['last_put_user']
            p = Player(last_put_user, self.bid, self.rid)
            #漏胡要过一圈才可以再胡
            card = p.out_card.members[-1]
            stop_pop_user_list = stop_pop_user.split(",")
            idx = stop_pop_user_list.index(uid)
            if len(stop_pop_user_list) != (idx+1):
                #给下一家可胡牌玩家推送通知
                next_player = stop_pop_user_list[idx+1]
                mid = self.incr_mid()
                tips = ["put_win"]
                nsq_pub({"b":self.bid, "u":str(next_player), "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
                return
            else:
                self.room['stop_pop_user'] = ""
                self.room['stop_pop_act'] = ""
                tips_user = self.check_pair_bar_tips(last_put_user, card)
                if tips_user:
                    logging.info(u"点炮胡玩家%s:pass, 有其他玩家%s要碰牌或杠" % (uid, tips_user))
                    return
        elif "bar_win" in stop_pop_act:
            self.room['stop_pop_user'] = ""
            self.room['stop_pop_act'] = ""
            last_get_user = self.room['last_get_user']
            self.next_pop(last_get_user, True)
            return
        elif "win" in stop_pop_act:
            player = Player(uid, self.bid, self.rid)
            player.score['flag'] = 'n'
            logging.info(u"用户胡牌点击取消执行漏胡%s" % uid)
            
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        
        if self.room['last_get_user'] != uid:
            self.next_pop()
        else:
            self.notify_put(uid)

    def pair_bar(self, uid, data):
        # 碰过别的牌, 然后自己摸到一张
        # card = data['card']
        stop_pop_user = self.room['stop_pop_user']
        if stop_pop_user and stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        p = Player(uid, self.bid, self.rid)
        card = p.current_card.members[-1]
        if not self.check_pair_bar(p.pair.members, card):
            logging.error(u"请求错误,该用户不能杠牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        p.current_card.remove(card)
        p.pair.remove(card)
        p.white_bar.append(card)
        stop_pop_card = False
        match_id = self.room['mid'] 
        if not match_id:
            member_len = len(self.members)
            bar_score = (member_len - 1)
            p.score['score'] = int(p.score['score']) + bar_score
            logging.info(u"用户%s明杠得%s分" % (uid, bar_score))
        mid = self.incr_mid()
        tips = []
        
        user_seat = self.members.index(uid)
        player_cnt = len(self.members)
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = self.members[idex]
            if member != uid:
                player = Player(member, self.bid, self.rid)
                if not match_id:
                    # 玩家有杠个扣1分
                    player.score['score'] = int(player.score['score']) - 1
                    logging.info(u"用户%s明杠,玩家%s各扣1分:%s" % (uid, member, player.score['score']))
                if tips:
                    pass
                else:
                    tips = []
                    if self.room['grab_bar_win'] == 'y':
                        if self.check_win(player, card):
                            tips = ["pair_bar_win"]
                            stop_pop_card = True
                            self.room['stop_pop_user'] = member
                            self.room['stop_pop_act'] = ",".join(tips)
            else:
                tips = []
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"pair_bar", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
        
        if not stop_pop_card:
            # 有抢杠胡的玩家,需要停止发牌  
            self.next_pop(uid, from_bar=True)
        
    def bar(self, uid, data):
        # 自己有三张,直接杠别人出的牌
        # card = data['card']
        # bar_uid = data['put_card_uid']
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        
        card = last_put_player.out_card.members[-1]
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        if not self.check_bar(current_card, card):
            logging.error(u"请求错误,该用户不能杠牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = last_put_player.out_card.pop()
        p.current_card.remove(card, 3)
        p.white_bar.append(card)
        self.room['last_get_user'] = uid
        match_id = self.room['mid']
        if not match_id:
            #只有非比赛房间才对杠扣分
            member_len = len(self.members)
            bar_score = member_len - 1
            p.score['score'] = int(p.score['score']) + bar_score
            logging.info(u"用户%s杠得3分:%s" % (uid, p.score['score']))
        mid = self.incr_mid()
        for member in self.members:
            if member == last_put_user:
                if not match_id:
                    player = Player(member, self.bid, self.rid)
                    player.score['score'] = int(player.score['score']) - bar_score
                    logging.info(u"用户%s点杠,扣3分:%s" % (member, player.score['score']))
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"bar", "card":card, "tips":[], "rid":self.rid, "uid":uid, "put_card_uid":last_put_user}})
        
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        self.next_pop(uid, from_bar=True)

    def pair(self, uid, data):
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        # card = data['card']
        # put_card_uid = data['put_card_uid']
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        card = last_put_player.out_card.members[-1]
        
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        if not self.check_pair(current_card, card):
            logging.error(u"请求错误,该用户不能碰牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = last_put_player.out_card.pop()
        p.score['put_flag'] = 'y'
        p.current_card.remove(card, 2)
        p.pair.append(card)
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"pair", "card":card, "tips":[], "rid":self.rid, "uid":uid, "put_card_uid":last_put_user}})
        # p = Player(self.room['lasy_player'], self.bid, self.rid)
        # p.out_card.remove(card, -1)
        self.room['last_get_user'] = uid
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        self.notify_put(uid)

    def pair_bar_win(self, uid, data):
        
        if "put_win" in self.room['stop_pop_act']:
            self.put_win(uid, data)
            return
        
        # 抢杠胡,杠家全包,退还之前杠的分数
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        #card = data['card']
        bar_uid = self.room['last_get_user']
        bar_player = Player(bar_uid, self.bid, self.rid)
        white_bar_member = bar_player.white_bar.members
        if white_bar_member:
            card = white_bar_member[-1]
        else:
            card = data.get("card", "")
        
        p = Player(uid, self.bid, self.rid)
        if not self.check_win(p, card):
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        all_horse_card = []
        horse_card = []
        horse_num = 0
        horse = self.room['horse']
        if horse:
            horse = int(horse)
            all_horse_card, horse_card = self.get_horse(horse, uid)
            horse_num = len(horse_card)
        
        member_len = len(self.members)
        match_id = self.room['mid']
        if match_id:
            #比赛杠没有分
            bar_score = 0
            deduct_bar_score = 0
            all_round = int(self.room['all_round'])
            game_round = int(self.room['game_round'])
            base_score = get_match_base_score(self.bid, match_id, all_round, game_round, self.rid)
        else:
            bar_score = 1
            deduct_bar_score = member_len - 1
            base_score = 1
        every_lose_score = 2 * base_score * (1 + horse_num)
        win_score = every_lose_score * (member_len - 1)
        logging.info(u"用户%s抢杠胡,中%s马,得%s分" % (uid, horse_num, win_score))
        p.score['score'] = int(p.score['score']) + win_score + bar_score
        mid = self.incr_mid()
        for member in self.members:
            if member != uid:
                player = Player(member, self.bid, self.rid)
                # 抢杠胡全包
                if member == bar_uid:
                    player.pair.append(card)
                    player.white_bar.remove(card)
                    player.score['score'] = int(player.score['score']) - deduct_bar_score - win_score
                    logging.info(u"用户%s抢杠胡,中%s马,抢杠全包:%s, 扣%s分" % (uid, horse_num, bar_uid, win_score))
                else:
                    if bar_score != 0:
                        player.score['score'] = int(player.score['score']) + bar_score
                        logging.info(u"用户%s抢杠胡,中%s马,抢杠全包,玩家退还杠扣的1分:%s" % (uid, horse_num, member))
            
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "card":card, "tips":[], "rid":self.rid, "uid":uid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}})
        self.game_over(uid, card, all_horse_card, horse_card, horse_num, False, "pair_bar_win", [u"抢杠胡",])

    def put_win(self, uid, data):
        #点炮胡
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        elif uid not in stop_pop_user.split(","):
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        card = last_put_player.out_card.members[-1]
        logging.info("last_put_user:%s, card:%s" % (last_put_user, card))
        p = Player(uid, self.bid, self.rid)
        if not self.check_win(p, card):
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        
        data['card'] = card
        #for member in self.members:
        #    if member == uid:
        #        continue
        #    mid = self.incr_mid()
        #    nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"put_card", "card":card, "tips":[], "rid":self.rid, "uid":last_put_user}})
        
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        all_horse_card = []
        horse_card = []
        horse_num = 0
        horse = self.room['horse']
        if horse:
            horse = int(horse)
            all_horse_card, horse_card = self.get_horse(horse, uid)
            horse_num = len(horse_card)
        
        member_len = len(self.members)
        match_id = self.room['mid']
        if match_id:
            #win_score = 1
            all_round = int(self.room['all_round'])
            game_round = int(self.room['game_round'])
            win_score = get_match_base_score(self.bid, match_id, all_round, game_round, self.rid)
        else:
            base_score = 1
            win_score = base_score * (1 + horse_num)
        #win_score = 2 * horse_num * (member_len - 1) + (member_len - 1)
        
        logging.info(u"房间:%s用户%s点炮胡,中%s马,得%s分" % (self.rid, uid, horse_num, win_score))
        #grab_bar_duty = self.room['grab_bar_duty']
        p.score['score'] = int(p.score['score']) + win_score
            
        mid = self.incr_mid()
        for member in self.members:
            if member != uid:
                player = Player(member, self.bid, self.rid)
                # 抢杠胡全包
                if member == last_put_user:
                    player.score['score'] = int(player.score['score']) - win_score
                    logging.info(u"房间:%s用户%s点炮胡,中%s马,点炮全包:%s, 扣%s分" % (self.rid, uid, horse_num, last_put_user, win_score))
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "card":card, "tips":[], "rid":self.rid, "uid":uid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}})
        self.game_over(uid, card, all_horse_card, horse_card, horse_num, False, "put_win", [u"点炮胡",])

class HZMaJiang(MaJiang):
    '''红中麻将'''
    def start(self):
        self.room['status'] = 'start'
        self.room['joker'] = '10'
        w = [str(x) for x in range(11, 20)] * 4
        d = [str(x) for x in range(21, 30)] * 4
        t = [str(x) for x in range(31, 40)] * 4
        f = ['10', ] * 4
        random.shuffle(w)
        random.shuffle(d)
        random.shuffle(t)
        random.shuffle(f)
        player_cnt = len(self.members)
        init_left_card = 136 - player_cnt * 13 - 1
        all_card = w + d + t + f
        init_left_card -= 24
        random.shuffle(all_card)
        
        dealer_seat = self.members.index(self.room['dealer'])
        for i in range(player_cnt):
            idex = (dealer_seat + i) % player_cnt
            uid = self.members[idex]
            player = Player(uid, self.bid, self.rid, True)
            card = []
            for i in range(13):
                card.append(all_card.pop())
                card.sort()
            player.current_card.clear()
            player.current_card.extend(card)
            mid = self.incr_mid()
            nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"status":"start", "left_card":init_left_card, "rid":self.rid, "mid":mid, "act":"game_start", "dealer":self.room['dealer'], "card":card, "game_round":self.room['game_round'], "all_round":self.room['all_round']}})
        dealer = self.room['dealer']
        self.room['last_get_user'] = dealer
        self.current_card.clear()
        self.current_card.extend(all_card)
        logging.info(u"红中麻将房间rid:%s,game_round:%s,开始发牌: %s" % (self.rid, self.room['game_round'], str(self.current_card.members)))
        self.next_pop(dealer)
            
    def trans_card(self, all_card):
        res = []
        for c in all_card:
            res.append(int(c))
        res.sort()
        return res
    
    def get_joker_cnt(self, card, joker):
        joker_cnt = 0
        for j in joker:
            k = card.count(j)
            joker_cnt += k
        return joker_cnt
    
    def get_jiang(self, card, joker=[]):
        res = []
        #card = self.trans_card(card)
        #joker = self.trans_card(joker)
        joker_cnt = 0
        for j in joker:
            k = card.count(j)
            joker_cnt += k
            #for i in range(k):
            #    card.remove(j)
        for c in set(card):
            if c in joker:
                continue
            if joker_cnt > 0 and c not in joker:
                res.append(c)
            else:
                if card.count(c) >= 2:
                    res.append(c)
        return res
    
    def get_n(self, card, jiang='', joker=[], priority='seq'):
        n = 0
        res = []
        left_res = []
        card.sort()
        joker_cnt = 0
        all_joker = []
        for j in joker:
            k = card.count(j)
            joker_cnt += k
            for i in range(k):
                all_joker.append(j)
                card.remove(j)
        if joker_cnt >= 4:
            return 4
        joker = all_joker
        if jiang:
            jiang_cnt = card.count(jiang)
            card.remove(jiang)  
            if jiang_cnt < 2:
                joker_cnt -= 1
                joker.pop()
            else:
                card.remove(jiang)
        while card:
            c = card.pop(0)
            card_num = card.count(c) 
            if card_num >= 2:
                n += 1
                card.remove(c)
                card.remove(c)
                res.append([c, c, c])
            elif card_num == 1:
                c2 = c + 1
                c3 = c + 2
                c4 = c + 3
                c2_cnt = card.count(c2)
                c3_cnt = card.count(c3)
                if c2_cnt == 2 and c3_cnt == 2 and c2/10==c/10 and c3/10==c/10:
                    n += 2
                    card.remove(c)
                    for i in range(2):
                        res.append([c, c2, c3])
                        card.remove(c2)
                        card.remove(c3)
                elif c2_cnt == 2 and c3_cnt == 1 and c2/10==c/10 and c3/10==c/10 and joker_cnt>=1:
                    n += 2
                    joker_cnt -= 1
                    jk = joker.pop()
                    res.append([c, c2, c3])
                    res.append([c, c2, jk])
                    card.remove(c)
                    card.remove(c2)
                    card.remove(c2)
                    card.remove(c3)
                elif joker_cnt >= 2:
                    n += 1
                    joker_cnt -= 1
                    jk = joker.pop()
                    card.remove(c)
                    res.append([c, c, jk])
                elif c2 in card and c3 in card and c2/10==c/10 and c3/10==c/10:
                    n += 1
                    card.remove(c2)
                    card.remove(c3)
                    res.append([c, c2, c3])
                elif joker_cnt == 1:
                    if priority != 'seq':
                        n += 1
                        joker_cnt -= 1
                        jk = joker.pop()
                        card.remove(c)
                        res.append([c, c, jk])
                    elif c2 in card and c4 not in card and c2/10==c/10 and c4/10==c/10:
                        n += 1
                        card.remove(c2)
                        joker_cnt -= 1
                        jk = joker.pop()
                        res.append([c, c2, jk])
                    elif c3 in card and c4 not in card and c3/10==c/10 and c4/10==c/10:
                        n += 1
                        card.remove(c3)
                        joker_cnt -= 1
                        jk = joker.pop()
                        res.append([c, jk, c3])
                    else:
                        n += 1
                        joker_cnt -= 1
                        jk = joker.pop()
                        card.remove(c)
                        res.append([c, c, jk])
                else:
                    #break
                    left_res.append(c)
            else:
                cs1 = c - 1
                cs1_cnt = card.count(cs1)
                if cs1_cnt >= 1 and cs1/10==c/10:
                    cs1_cnt = 1
                else:
                    cs1_cnt = 0
                cs2 = c - 2
                cs2_cnt = card.count(cs2)
                if cs2_cnt >= 1 and cs2/10==c/10:
                    cs2_cnt = 1
                else:
                    cs2_cnt = 0
                    
                c2 = c + 1
                c2_cnt = card.count(c2)
                if c2_cnt >= 1 and c2/10==c/10:
                    c2_cnt = 1
                else:
                    c2_cnt = 0
                c3 = c + 2
                c3_cnt = card.count(c3)
                if c3_cnt >= 1 and c3/10==c/10:
                    c3_cnt = 1
                else:
                    c3_cnt = 0
                if c2_cnt + c3_cnt + joker_cnt >= 2:
                    n += 1
                    tmp_res = [c, ]
                    need_joker = 2 - (c2_cnt + c3_cnt)
                    joker_cnt -= need_joker
                    for i in range(c2_cnt):
                        card.remove(c2)
                        tmp_res.append(c2)
                    for i in range(c3_cnt):
                        card.remove(c3)
                        tmp_res.append(c3)
                    for i in range(need_joker):
                        jk = joker.pop()
                        tmp_res.append(jk)
                    res.append(tmp_res)
                elif cs1_cnt + c2_cnt + joker_cnt >= 2:
                    n += 1
                    tmp_res = [c, ]
                    need_joker = 2 - (cs1_cnt + c2_cnt)
                    joker_cnt -= need_joker
                    for i in range(c2_cnt):
                        card.remove(c2)
                        tmp_res.append(c2)
                    for i in range(cs1_cnt):
                        card.remove(cs1)
                        tmp_res.append(c3)
                    for i in range(need_joker):
                        jk = joker.pop()
                        tmp_res.append(jk)
                    res.append(tmp_res)
                elif cs1_cnt + cs2_cnt + joker_cnt >= 2:
                    n += 1
                    tmp_res = [c, ]
                    need_joker = 2 - (cs1_cnt + cs2_cnt)
                    joker_cnt -= need_joker
                    for i in range(cs1_cnt):
                        card.remove(cs1)
                        tmp_res.append(c2)
                    for i in range(cs2_cnt):
                        card.remove(cs2)
                        tmp_res.append(cs2)
                    for i in range(need_joker):
                        jk = joker.pop()
                        tmp_res.append(jk)
                    res.append(tmp_res)
                else:
                    # break
                    left_res.append(c)
        if joker_cnt % 3 == 0:
            n += (joker_cnt / 3)
        win_card = []
        return n, res, left_res, win_card

    def get_max_n(self, card_str, joker_list=[]):
        allcard = self.trans_card(card_str)
        ccc = self.trans_card(card_str)
        joker = self.trans_card(joker_list)
        joker_cnt = self.get_joker_cnt(allcard, joker)
        if joker_cnt >= 4:
            #4张鬼牌可直接胡
            return 5
        jiang_list = self.get_jiang(allcard, joker)
        if not jiang_list:
            return 0
        #print jiang_list, '可以做将的列表'
        res = [0, ]
        for jiang in sorted(jiang_list):
            allcard = self.trans_card(card_str)
            #logging.info(u"判断胡牌:%s,%s" % (self.rid, jiang))
            n, rs, left_res, win_card = self.get_n(allcard, jiang, joker)
            res.append(n+1)
        return max(res)

    def check_win_card(self, player, joker=[]):
        w = [str(x) for x in range(11, 20)]
        d = [str(x) for x in range(21, 30)]
        t = [str(x) for x in range(31, 40)]
        all_card = w + d + t
        win_card = []
        for card in all_card:
            if self.check_win(player, card):
                win_card.append(card)
        return win_card
    
    def check_win(self, player, card='', joker_list=[]):
        # 检查
        jk = self.room['joker']
        if jk:
            joker_list = jk.split(",")
        else:
            joker_list = []
        n = 0
        n += len(player.dark_bar)
        n += len(player.white_bar)
        n += len(player.pair)
        current_card = player.current_card.members
        if card:
            current_card.append(card)
        if n == 0 and self.room['seven_pair_win'] == 'y':
            if self.check_seven_pairs(current_card, joker_list):
                return True
        if len(current_card) != ((4 - n) * 3 + 2):
            logging.info(u"该玩家手牌相公不能胡牌:%s" % player.uid)
            return False
        #max_n = self.get_max_n(current_card, joker_list)
        #logging.debug(u"用户牌型最大n:%s" % max_n)
        #if n + max_n >= 5:
        mj = MaJiangCheck()
        if mj.check_win(n, current_card, '', joker_list):
            return True
        return False
    
class CSMaJiang(ZZMaJiang):
    '''长沙麻将, 胡法: 点炮,自摸,海底自摸,海底点炮,杠上开花,杠上点炮,天胡,地胡(平胡)
    '''
    def is_sixi(self, all_card):
        '''四喜,小胡自摸'''
        card = self.trans_card(all_card)
        for c in set(card):
            c_cnt = card.count(c)
            if c_cnt == 4:
                return 'sixi'
        return False
    
    def is_banbanhu(self, all_card):
        '''板板胡,手牌没有258,小胡自摸'''
        card = self.trans_card(all_card)
        for c in set(card):
            if c%10 in (2, 5, 8):
                return False
        return 'banbanhu'
    
    def is_queyise(self, all_card):
        '''缺一色, 小胡自摸'''
        card = self.trans_card(all_card)
        color = {}
        for cc in set(card):
            c = str(cc/10)
            d = cc % 10
            if c in color:
                color[c]['num'] += 1
            else:
                color[c] = {"num":1, "five_num":0}
            if d == 5:
                color[c]['five_num'] += 1
                
        if len(color.keys()) <= 2:
            return 'queyise'
        for k in color.keys():
            if color[k]['num'] == 1 and color[k]['five_num'] == 1:
                return 'queyise' 
        return False
    
    def is_liuliushun(self, all_card):
        '''六六顺, 小胡自摸'''
        card = self.trans_card(all_card)
        triple_cnt = 0
        for c in set(card):
            if card.count(c) == 3:
                triple_cnt += 1
        if triple_cnt >= 2:
            return 'liuliushun'
        return False
    
    def get_jiang(self, all_card, free_jiang=True):
        res = []
        card = self.trans_card(all_card)
        for c in set(card):
            if card.count(c) >= 2:
                if free_jiang:
                    res.append(c)
                elif c%10 in (2,5,8):
                    res.append(c)
        return res
    
    def is_pinghu(self, all_card, has_n=0, win_type='put_win', free_jiang=False):
        '''平胡,258将'''
        jiang_list = self.get_jiang(all_card, free_jiang)
        res = [0,]
        for jiang in jiang_list:
            card = self.trans_card(all_card)
            n = self.get_n(card, jiang)
            res.append(n)
        if max(res)+has_n >= 5:
            if win_type == "put_win":
                return 'put_pinghu' 
            return 'pinghu'
        return False
    
    def get_n(self, all_card, jiang, joker=[]):
        n = 0
        # print "===当将牌为%s时,各种排列组合为==" % jiang
        res = []
        jiang = int(jiang)
        card = self.trans_card(all_card)
        card.sort()
        if jiang and card.count(jiang) >= 2:
            card.remove(jiang)
            card.remove(jiang)
            n += 1
        while card:
            c = card.pop(0)
            if card.count(c) >= 2:
                n += 1
                card.remove(c)
                card.remove(c)
                res.append([c, c, c])
            elif c > 40:
                break
            else:
                c2 = c + 1
                c3 = c + 2
                if c2 in card and c3 in card:
                    card.remove(c2)
                    card.remove(c3)
                    res.append([c, c2, c3])
                    n += 1
                else:
                    break
        return n

    def is_qixiaodui(self, all_card):
        '''七小对'''
        pair = 0
        bomb = 0
        card = self.trans_card(all_card)
        for c in set(card):
            if card.count(c) == 4:
                bomb += 1
                pair += 2
            elif card.count(c) == 2:
                pair += 1
        if pair == 7:
            if bomb >= 2:
                '''双豪华七小对'''
                return 'two_qixiaodui'
            elif bomb == 1:
                '''豪华七小对'''
                return 'one_qixiaodui' 
            return 'qixiaodui'
        return False
    
    def is_pengpenghu(self, all_card, has_n=0):
        '''碰碰胡,AAABBBCCCDDD乱将'''
        res = [0]
        jiang_list = self.get_jiang(all_card)
        for jiang in jiang_list:
            card = self.trans_card(all_card)
            card.remove(jiang)
            card.remove(jiang)
            triple = 0
            for c in set(card):
                if card.count(c) == 3:
                    triple += 1
            res.append(triple+1)
        if max(res)+has_n >= 5:
            return 'pengpenghu'
        return False
    
    def is_jiangjianghu(self, all_card):
        '''将将胡,每张牌都是258'''
        card = self.trans_card(all_card)
        for c in set(card):
            if c%10 not in (2,5,8):
                return False
        return 'jiangjianghu'
    
    def is_qingyise(self, all_card):
        '''清一色'''
        card = self.trans_card(all_card)
        color = card[0]/10
        for c in set(card):
            if c/10 != color:
                return False
        return 'qingyise'
    
    def is_dandiao(self, all_card, jiang, has_n):
        '''全求人'''
        if len(all_card) != 2:
            return False
        n = self.get_n(all_card, jiang)
        if n+has_n >= 5:
            return 'dandiao'
        return False
    
    def check_win(self, player, card='', joker=[]):
        '''检查是否符合自模糊'''
        # 检查
        n = 0
        dark_bar = player.dark_bar.members
        white_bar = player.white_bar.members
        pair = player.pair.members
        eat = player.eat.members
        n += len(dark_bar)
        n += len(white_bar)
        n += len(pair)
        n += len(eat)
        current_card = player.current_card.members
        if card:
            current_card.append(card)
        
        #tianhu = False
        #dihu = False
        #out_card = self.out_card.members
        #if not out_card:
        #    tianhu = True
        #elif len(out_card) == 1:
        #    dihu = True
        logging.info(u"长沙判断用户%s是否胡牌:%s" % (player.uid, str(current_card)))
        if len(current_card) != ((4 - n) * 3 + 2):
            logging.info(u"该玩家手牌相公不能胡牌:%s" % player.uid)
            
            return []
        if self.is_qixiaodui(current_card):
            return True
        elif self.is_pengpenghu(current_card, len(pair)+len(dark_bar)+len(white_bar)):
            return True
        put_flag = player.score['put_flag']
        if not put_flag and n == 0:
            #只能是起手的牌符合要求才行
            sixi = self.is_sixi(current_card[:-1])
            if sixi:
                return sixi
            liuliushun = self.is_liuliushun(current_card[:-1])
            if liuliushun:
                return liuliushun
            banbanhu = self.is_banbanhu(current_card)
            if banbanhu:
                return banbanhu
            queyise = self.is_queyise(current_card)
            if queyise:
                return queyise
        all_card = []
        all_card.extend(current_card)
        if dark_bar:
            all_card.extend(dark_bar)
        if white_bar:
            all_card.extend(white_bar)
        if pair:
            all_card.extend(pair)
        if eat:
            for eat_card in eat:
                all_card.extend(eat_card.split(","))
        if self.is_jiangjianghu(all_card):
            return True
            
        qingyise = self.is_qingyise(all_card)
        if qingyise or len(current_card) <= 2: 
            free_jiang = True
        else:
            free_jiang = False
        if self.is_pinghu(current_card, n, "win", free_jiang):
            return True
        return False
    
    def get_win_score(self, win_type_list):
        score = 0
        win_type_score = {"sixi":2,"banbanhu":2,"queyise":2,"liuliushun":2,"put_pinghu":1,"pinghu":2, "pengpenghu":6,"jiangjianghu":6,"qingyise":6,"haidi_win":6,
                 "haidi_put_win":6,"qixiaodui":6,"one_qixiaodui":12,"two_qixiaodui":18,"bar_win":6,"pair_bar_win":6,"bar_put_win":6,
                 "dandiao":6, "tianhu":6, "dihu":6, "quanqiuren":6,
                 }
        for win_type in win_type_list:
            score += win_type_score[win_type]
        return score
    
    def trans_win_type(self, win_type_list):
        res = []
        win_type_name = {"sixi":{"score":2, "name":u"四喜"}, "banbanhu":{"score":2, "name":u"板板胡"},"queyise":{"score":2, "name":u"缺一色"},
                         "liuliushun":{"score":2, "name":u"六六顺"},"put_pinghu":{"score":1, "name":u"平胡"}, "pinghu":{"score":2, "name":u"平胡"}, "pengpenghu":{"score":6, "name":u"碰碰胡"},
                         "jiangjianghu":{"score":6, "name":u"将将胡"},"qingyise":{"score":6, "name":u"清一色"},"haidi_win":{"score":6, "name":u"海底捞月"},
                         "haidi_put_win":{"score":6, "name":u"海底炮"},"qixiaodui":{"score":6, "name":u"七小对"},"one_qixiaodui":{"score":12, "name":u"豪华七小对"},
                         "two_qixiaodui":{"score":18, "name":u"双豪华七小对"},"bar_win":{"score":6, "name":u"杠上开花"},"pair_bar_win":{"score":6, "name":u"抢杠胡"},
                         "bar_put_win":{"score":6, "name":u"杠上炮"},"dandiao":{"score":6, "name":u"全求人"}, "tianhu":{"score":6, "name":u"天胡"}, "dihu":{"score":6, "name":u"地胡",},
                         }
        for win_type in win_type_list:
            msg = u"%s %s分" % (win_type_name[win_type]['name'], win_type_name[win_type]['score'])
            res.append(msg)
        return res
    
    def get_win_type(self, player, card=''):
        '''获取用户符合自模糊的哪种类型'''
        n = 0
        dark_bar = player.dark_bar.members
        white_bar = player.white_bar.members
        pair = player.pair.members
        eat = player.eat.members
        n += len(dark_bar)
        n += len(white_bar)
        n += len(pair)
        n += len(eat)
        current_card = player.current_card.members
        if card:
            current_card.append(card)
        if len(current_card) != ((4 - n) * 3 + 2):
            logging.info(u"该玩家手牌相公不能胡牌:%s" % player.uid)
            return []
        res = []
        qixiaodui = self.is_qixiaodui(current_card)
        if qixiaodui:
            res.append(qixiaodui)
        
        pinghu = self.is_pinghu(current_card, n, 'win')
        if pinghu:
            res.append(pinghu)
        put_flag = player.score['put_flag']
        if not put_flag:
            liuliushun = self.is_liuliushun(current_card)
            if liuliushun:
                res.append(liuliushun)
            #这几种牌型只能自摸
            sixi = self.is_sixi(current_card)
            if sixi:
                res.append(sixi)
                
        pengpenghu = self.is_pengpenghu(current_card, len(pair)+len(dark_bar)+len(white_bar))
        if pengpenghu:
            res.append(pengpenghu)
        
        dandiao = self.is_dandiao(current_card, current_card[-1], n)
        if dandiao:
            res.append(dandiao)
        all_card = []
        all_card.extend(current_card)
        if dark_bar:
            all_card.extend(dark_bar)
        if white_bar:
            all_card.extend(white_bar)
        if pair:
            all_card.extend(pair)
        if eat:
            for eat_card in eat:
                all_card.extend(eat_card.split(","))
        jiangjianghu = self.is_jiangjianghu(all_card)
        if jiangjianghu:
            res.append(jiangjianghu)
        
        if not put_flag:
            banbanhu = self.is_banbanhu(all_card)
            if banbanhu:
                res.append(banbanhu)
            quyise = self.is_queyise(all_card)
            if quyise:
                res.append(quyise)
        qingyise = self.is_qingyise(all_card)
        if qingyise:
            res.append(qingyise)
        
        if len(res) > 1:
            if "pinghu" in res:
                res.remove("pinghu")
        return res
    
    def get_eat_card(self, all_card, card):
        '''获取可吃的牌'''
        card = int(card)
        if card > 40:
            return []
        c = card % 10
        n = card / 10
        res = []
        point_res = []
        if c == 9:
            point_res = [[7, 8]]
        elif c == 8:
            point_res = [[6, 7], [7, 9]]
        elif c == 7:
            point_res = [[5, 6], [6, 8], [8, 9]]
        elif c == 6:
            point_res = [[4, 5], [5, 7], [7, 8]]
        elif c == 5:
            point_res = [[3, 4], [4, 6], [6, 7]]
        elif c == 4:
            point_res = [[2, 3], [3, 5], [5, 6]]
        elif c == 3:
            point_res = [[1, 2], [2, 4], [4, 5]]
        elif c == 2:
            point_res = [[1, 3], [3, 4]]
        elif c == 1:
            point_res = [[2, 3]]
        for [s, e] in point_res:
            c1 = str(n*10+s)
            c2 = str(n*10+e)
            if c1 in all_card and c2 in all_card:
                res.append([c1, c2])
        return res
    
    def check_eat(self, all_card, card):
        '''判断能否吃card牌'''
        card = int(card)
        all_card = [int(x) for x in all_card]
        all_card.append(card)
        all_card.sort()
        if len(all_card) == 3 and (all_card[0]+1) == all_card[1] and (all_card[0]+2) == all_card[2]:
            return True
        return False
    
    def check_put_win(self, player, card='', joker=[]):
        '''点炮胡检查'''
        n = 0
        dark_bar = player.dark_bar.members
        white_bar = player.white_bar.members
        pair = player.pair.members
        eat = player.eat.members
        n += len(dark_bar)
        n += len(white_bar)
        n += len(pair)
        n += len(eat)
        current_card = player.current_card.members
        if card:
            current_card.append(card)
        if len(current_card) != ((4 - n) * 3 + 2):
            logging.info(u"该玩家手牌相公不能胡牌:%s" % player.uid)
            return False
        if self.is_qixiaodui(current_card):
            return True
        elif self.is_pengpenghu(current_card, len(pair)+len(dark_bar)+len(white_bar)):
            return True
        all_card = []
        all_card.extend(current_card)
        if dark_bar:
            all_card.extend(dark_bar)
        if white_bar:
            all_card.extend(white_bar)
        if pair:
            all_card.extend(pair)
        if eat:
            for eat_card in eat:
                all_card.extend(eat_card.split(","))
        jiangjianghu = self.is_jiangjianghu(all_card)
        if jiangjianghu:
            return True
        if self.is_qingyise(all_card) or len(current_card) <= 2:
            free_jiang = True
        else:
            free_jiang = False
        if self.is_pinghu(current_card, n, "put_win", free_jiang):
            return True
        return False
    
    def get_put_win_type(self, player, card='', joker=[]):
        '''点炮胡可胡的类型'''
        n = 0
        res = []
        dark_bar = player.dark_bar.members
        white_bar = player.white_bar.members
        pair = player.pair.members
        eat = player.eat.members
        n += len(dark_bar)
        n += len(white_bar)
        n += len(pair)
        n += len(eat)
        current_card = player.current_card.members
        if card:
            current_card.append(card)
        if len(current_card) != ((4 - n) * 3 + 2):
            logging.info(u"该玩家手牌相公不能胡牌:%s" % player.uid)
            return []
        qixiaodui = self.is_qixiaodui(current_card)
        if qixiaodui:
            res.append(qixiaodui)
        else:
            pinghu = self.is_pinghu(current_card, n, "put_win")
            if pinghu:
                res.append(pinghu)
            pengpenghu = self.is_pengpenghu(current_card, len(pair)+len(dark_bar)+len(white_bar))
            if pengpenghu:
                res.append(pengpenghu)
            dandiao = self.is_dandiao(current_card, card, n)
            if dandiao:
                res.append(dandiao)
        all_card = []
        all_card.extend(current_card)
        if dark_bar:
            all_card.extend(dark_bar)
        if white_bar:
            all_card.extend(white_bar)
        if pair:
            all_card.extend(pair)
        if eat:
            for eat_card in eat:
                all_card.extend(eat_card.split(","))
        jiangjianghu = self.is_jiangjianghu(all_card)
        if jiangjianghu:
            res.append(jiangjianghu)
        qingyise = self.is_qingyise(all_card)
        if qingyise:
            res.append(qingyise)
        
        if len(res) > 1:
            if "put_pinghu" in res:
                res.remove("put_pinghu")
            if "pinghu" in res:
                res.remove("pinghu")
        return res
    

    def next_pop(self, uid=None, from_bar=False):
        # 发牌逻辑
        if not uid:
            last_get_user = self.room['last_get_user']
            logging.info("next_pop, last:%s" % last_get_user)
            last_player_seat = self.members.index(str(last_get_user))
            idx = (last_player_seat + 1) % len(self.members)
            uid = self.members[idx]
        
        if len(self.current_card.members) <= int(self.room['horse']):
            logging.info("over===cccccccccc========%s" % len(self.current_card.members))
            self.game_over()
            return
        card = self.current_card.pop()
        if not card:
            logging.info("over===========")
            self.game_over()
            return
        self.room['last_get_user'] = uid
        if from_bar:
            self.room['bar_get_card'] = card
        else: 
            self.room['bar_get_card'] = ''
            
        p = Player(uid, self.bid, self.rid)
        #检查漏胡标记, 摸牌后清除状态
        p_flag = p.score['flag']
        if p_flag == 'n':
            p.score['flag'] = ''
        tips = []
        bar_card = []
        current_user = Hash("%s_%s" % (self.bid, uid))
        win_type = ""
        if self.room['mid'] and (current_user['online'] != 'y' or current_user['rid'] != self.rid):
            tips = []
            #离线用户不检查牌型
        else:
            win_type = self.check_win(p, card)
            if win_type:
                tips.append("win")
            
            current_card = p.current_card.members
            init_dark_bar = self.check_init_dark_bar(current_card)
            if self.check_bar(current_card, card):
                tips.append("dark_bar")
                bar_card.append(card)
            elif self.check_pair_bar(p.pair.members, card):
                tips.append("pair_bar")
                
            if init_dark_bar:
                tips.append("dark_bar")
                bar_card.extend(init_dark_bar)
            
        if tips:
            self.room['stop_pop_user'] = uid
            self.room['stop_pop_act'] = ",".join(tips)
        p.current_card.append(card)
        mid = self.incr_mid()
        left_card = len(self.current_card)
        for member in self.members:
            #if member != uid:
            #    tips = []
            data = {"b":self.bid, "u":str(member), "t":"game", "d":{"left_card":left_card, "mid":mid, "uid":uid, "act":"get_card", "card":card, "tips":tips, "bar_card":bar_card, "rid":self.rid}}
            nsq_pub(data)
        
        if not self.out_card and win_type in ("sixi", "banbanhu", "liuliushun", "queyise"):
            self.win(uid, {"card":card})
            return
        
        if not tips:
            self.notify_put(uid)
        
        if self.room['mid'] and (current_user['online'] != 'y' or current_user['rid'] != self.rid):
            self.room['stop_pop_user'] = ""
            time.sleep(0.5)
            self.put_card(uid, {"card":card})
            
    def put_card(self, uid, data, from_pass=False, repeat_user=[]):
        # 玩家出牌逻辑
        repeat = "n"
        uid = str(uid)
        #是否重复发牌给客户端
        stop_pop_user = self.room['stop_pop_user']
        if stop_pop_user and stop_pop_user != str(uid):
            logging.error(u"玩家:%s有提示未处理,轮不到%s出牌" % (stop_pop_user, uid))
            return
        last_put_user = self.room['last_put_user']
        if uid == last_put_user:
            logging.error(u"玩家:%s不能连续出牌" % (uid))
            return
        card = data['card']
        p = Player(uid, self.bid, self.rid)
        if p.current_card.count(card) == 0:
            logging.error(u"出牌错误,该玩家没有该牌")
            return
        p.out_card.append(card)
        p.current_card.remove(card)
        self.room['last_put_user'] = uid
        self.room['last_get_user'] = uid
        p.score['put_flag'] = 'y'
        members = self.members
        player_cnt = len(members)
        mid = self.incr_mid()
        put_win_user = []
        #按照玩家座位顺序检查是否有胡牌可能
        match_id = self.room['mid']
        user_seat = members.index(uid)
        tips = []
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = members[idex]
            if member != uid:
                member_info = Hash("%s_%s" % (self.bid, member))
                if match_id and (member_info['online'] != 'y' or member_info['rid'] != self.rid):
                    tips = []
                else:
                    member_player = Player(member, self.bid, self.rid)
                    tips = []
                    if p.score['flag'] != 'n': 
                        if self.check_put_win(member_player, card):
                            put_win_user.append(member)
                win_card = []
            else:
                win_card = []
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"win_card":win_card, "repeat":repeat, "mid":mid, "act":"put_card", "card":card, "tips":[], "rid":self.rid, "uid":uid}})
            
        if len(put_win_user) >= 1:
            #点炮胡的情况
            self.room['stop_pop_user'] = ",".join(put_win_user)
            self.room['stop_pop_act'] = "put_win"
            tips = ["put_win",]
            mid = self.incr_mid()
            nsq_pub({"b":self.bid, "u":str(put_win_user[0]), "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
            return
        
        res = self.check_pair_bar_tips(uid, card)
        if res:
            logging.info(u"有玩家%s要碰牌或杠:%s" % (res, card))
            return
        res = self.check_eat_tips(uid, card)
        if res:
            logging.info(u"有玩家%s要吃牌:%s" % (res, card))
            return
        
        #所有提示都没有的情况,继续下家发牌
        self.next_pop()
            
    def check_pair_bar_tips(self, last_put_user='', card=''):
        if not last_put_user:
            last_put_user = self.room['last_put_user']
            last_put_player = Player(last_put_user, self.bid, self.rid)
            card = last_put_player.out_card.members[-1]
        
        members = self.members
        user_seat = members.index(last_put_user)
        next_idex = (user_seat + 1) % len(members)
        next_member = members[next_idex]
        tips_user = ''
        eat_card_list = []
        for member in members:
            if member != last_put_user:
                member_info = Hash("%s_%s" % (self.bid, member))
                if self.room['mid'] and (member_info['online'] != 'y' or member_info['rid'] != self.rid):
                    tips = []
                else:
                    player = Player(member, self.bid, self.rid)
                    current_card = player.current_card.members
                    tips = [] 
                    if self.check_bar(current_card, card):
                        tips.append("bar")
                        tips.append("pair")
                    elif self.check_pair(current_card, card):
                        tips.append("pair")
                        
                    if tips and member == next_member:
                        eat_card_list = self.get_eat_card(current_card, card)
                        if eat_card_list:
                            tips.append("eat")
                    else:
                        eat_card_list = []
                            
                if tips:
                    tips_user = member
                    self.room['stop_pop_user'] = member
                    self.room['stop_pop_act'] = ",".join(tips)
                    mid = self.incr_mid()
                    if tips_user:
                        nsq_pub({"b":self.bid, "u":tips_user, "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":tips_user, "eat_card":eat_card_list}})
                        return tips_user
        return False
    
    def check_eat_tips(self, last_put_user='', card=''):
        if not last_put_user:
            last_put_user = self.room['last_put_user']
            last_put_player = Player(last_put_user, self.bid, self.rid)
            card = last_put_player.out_card.members[-1]
        
        members = self.members
        user_seat = members.index(last_put_user)
        next_idex = (user_seat + 1) % len(members)
        next_member = members[next_idex]
        next_player = Player(next_member, self.bid, self.rid)
        next_player_card = next_player.current_card.members
        tips = []
        eat_card_list = self.get_eat_card(next_player_card, card)
        if eat_card_list:
            tips = ['eat',]
            self.room['stop_pop_user'] = next_member
            self.room['stop_pop_act'] = ",".join(tips)
            mid = self.incr_mid()
            nsq_pub({"b":self.bid, "u":next_member, "t":"game", "d":{"act":"tips", "mid":mid, "card":card, "tips":tips, "rid":self.rid, "uid":next_member, "eat_card":eat_card_list}})
            return next_member
        return False
    
    def pass_card(self, uid, data):
        logging.info("pass:%s" % uid)
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            return
        elif uid not in stop_pop_user.split(","):
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            return
        last_put_user = self.room['last_put_user']
        stop_pop_act = self.room['stop_pop_act']
        p = Player(last_put_user, self.bid, self.rid)
        card = p.out_card.members[-1]
        if "put_win" in stop_pop_act:
            p.score['flag'] = 'n'
            stop_pop_user_list = stop_pop_user.split(",")
            idx = stop_pop_user_list.index(uid)
            if len(stop_pop_user_list) != (idx+1):
                #给下一家可胡牌玩家推送通知
                next_player = stop_pop_user_list[idx+1]
                mid = self.incr_mid()
                tips = ["put_win",]
                nsq_pub({"b":self.bid, "u":str(next_player), "t":"game", "d":{"mid":mid, "act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
                return
            else:
                #所有可点炮胡的玩家都通知完
                self.room['stop_pop_user'] = ""
                self.room['stop_pop_act'] = ""
                tips_user = self.check_pair_bar_tips(last_put_user, card)
                if tips_user:
                    logging.info(u"点炮胡玩家%s:pass, 有其他玩家%s要碰牌或杠" % (uid, tips_user))
                    return
                tips_user = self.check_eat_tips(last_put_user, card)
                if tips_user:
                    logging.info(u"点炮胡玩家%s:pass, 有其他玩家:%s要吃牌" % (uid, tips_user))
                    return
        elif "bar_win" in stop_pop_act:
            self.room['stop_pop_user'] = ""
            self.room['stop_pop_act'] = ""
            last_get_user = self.room['last_get_user']
            self.next_pop(last_get_user, True)
            return
        
        elif "pair" in stop_pop_act or "bar" in stop_pop_act:
            self.room['stop_pop_user'] = ""
            self.room['stop_pop_act'] = ""
            if "eat" not in stop_pop_act:
                tips_user = self.check_eat_tips(last_put_user, card)
                if tips_user:
                    logging.info(u"碰,杠玩家%s:pass, 有其他玩家:%s要吃牌" % (uid, tips_user))
                    return
        
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        
        if self.room['last_get_user'] != uid:
            self.next_pop()
        else:
            self.notify_put(uid)
    

    def pair_bar(self, uid, data):
        # 碰过别的牌, 然后自己摸到一张，杠没有分
        # card = data['card']
        stop_pop_user = self.room['stop_pop_user']
        if stop_pop_user and stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            return
        p = Player(uid, self.bid, self.rid)
        card = p.current_card.members[-1]
        if not self.check_pair_bar(p.pair.members, card):
            logging.error(u"请求错误,该用户不能杠牌:%s" % card)
            return
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        p.current_card.remove(card)
        p.pair.remove(card)
        p.white_bar.append(card)
        stop_pop_card = False
        mid = self.incr_mid()
        tips = []
        user_seat = self.members.index(uid)
        player_cnt = len(self.members)
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = self.members[idex]
            if member != uid:
                player = Player(member, self.bid, self.rid)
                if tips:
                    pass
                else:
                    tips = []
                    if self.room['grab_bar_win'] == 'y':
                        if self.check_win(player, card):
                            tips = ["pair_bar_win"]
                            stop_pop_card = True
                            self.room['stop_pop_user'] = member
                            self.room['stop_pop_act'] = ",".join(tips)
            else:
                tips = []
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"pair_bar", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
        
        if not stop_pop_card:
            # 有抢杠胡的玩家,需要停止发牌  
            self.next_pop(uid, from_bar=True)
        
    def bar(self, uid, data):
        # 自己有三张,直接杠别人出的牌
        # card = data['card']
        # bar_uid = data['put_card_uid']
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            return
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        
        card = last_put_player.out_card.members[-1]
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        if not self.check_bar(current_card, card):
            logging.error(u"请求错误,该用户不能杠牌:%s" % card)
            return
        p.score['put_flag'] = 'y'
        card = last_put_player.out_card.pop()
        p.current_card.remove(card, 3)
        p.white_bar.append(card)
        mid = self.incr_mid()
        self.room['last_get_user'] = uid
        tips = []
        stop_pop_card = False
        user_seat = self.members.index(uid)
        player_cnt = len(self.members)
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = self.members[idex]
            if member != uid:
                player = Player(member, self.bid, self.rid)
                if tips:
                    pass
                else:
                    tips = []
                    if self.room['grab_bar_win'] == 'y':
                        if self.check_win(player, card):
                            tips = ["pair_bar_win"]
                            stop_pop_card = True
                            self.room['stop_pop_user'] = member
                            self.room['stop_pop_act'] = "pair_bar_win"
            else:
                tips = []
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"bar", "card":card, "tips":tips, "rid":self.rid, "uid":uid, "put_card_uid":last_put_user}})
        
        if not stop_pop_card:
            self.room['stop_pop_user'] = ""
            self.room['stop_pop_act'] = ""
            self.next_pop(uid, from_bar=True)
        
    def eat(self, uid, data):
        '''吃牌'''
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            return
        # card = data['card']
        # put_card_uid = data['put_card_uid']
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        card = last_put_player.out_card.members[-1]
        
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        eat_card_list = self.get_eat_card(current_card, card)
        if not eat_card_list:
            logging.error(u"请求错误,该用户不能吃这张牌:%s" % card)
            return
        
        eat_card = data['eat_card']
        c1 = eat_card[0]
        c2 = eat_card[1]
        if c1 not in current_card or c2 not in current_card or not self.check_eat(eat_card, card):
            logging.error(u"吃牌错误,该用户%s不能吃这张牌:%s" % (uid, card))
            return
        card = last_put_player.out_card.pop()
        p.current_card.remove(eat_card[0], 1)
        p.current_card.remove(eat_card[1], 1)
        p.score['put_flag'] = 'y'
        eat_card_list = [c1, c2, card]
        eat_card_list.sort()
        p.eat.append(",".join(eat_card_list))
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"eat", "card":card, "eat_card":eat_card_list, "tips":[], "rid":self.rid, "uid":uid, "put_card_uid":last_put_user}})
        self.room['last_get_user'] = uid
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        self.notify_put(uid)
        
    def win(self, uid, data):
        if self.room['status'] != 'start':
            logging.error(u"该轮游戏已结束")
            return
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            return
        # card = data.get('card', '')
        
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        card = current_card[-1]
        # if not self.check_win(p, card):
        if not self.check_win(p, ''):
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            return
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        all_horse_card = []
        horse_card = []
        horse_num = 0
        horse = self.room['horse']
        if horse:
            horse = int(horse)
            all_horse_card, horse_card = self.get_horse(horse, uid)
            horse_num = len(horse_card)
        else:
            horse = 0
        member_len = len(self.members)
        win_type_list = self.get_win_type(p, '')
        
        dealer = self.room['dealer']
        #dealer_player = Player(dealer, self.bid, self.rid)
        #out_card = dealer_player.out_card.members
        if str(uid) == dealer and "sixi" not in win_type_list and "liuliushun" not in win_type_list and "banbanhu" not in win_type_list and "queyise" not in win_type_list:
            if not p.score['put_flag']:
                win_type_list.append("tianhu")
        else:
            if self.room['bar_get_card'] == card:
                #杠上开花
                win_type_list.append("bar_win")
            room_left_card = self.current_card.members
            if not room_left_card or len(room_left_card) == horse:
                #海底捞月
                win_type_list.append("haidi_win")
        score = self.get_win_score(win_type_list)
        win_type_list = self.trans_win_type(win_type_list)
        logging.info(u"自模糊:%s" % str(win_type_list))
        #base_score = 1
        if score > 12:
            score = 12
        every_lose_score = score + horse_num * 2
        win_score = every_lose_score * (member_len - 1)
        
        p.score['score'] = int(p.score['score']) + win_score
        
        logging.info(u"用户%s自摸胡牌,中%s马,得%s分" % (uid, horse_num, win_score))
        for member in self.members:
            if member != uid:
                player = Player(member, self.bid, self.rid)
                player.score['score'] = int(player.score['score']) - every_lose_score
                logging.info(u"用户%s自摸胡牌,中%s马,玩家各扣%s分" % (uid, horse_num, every_lose_score))
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "card":card, "tips":[], "rid":self.rid, "uid":uid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}})
        self.game_over(uid, card, all_horse_card, horse_card, horse_num, win_type="win", win_type_list=win_type_list)
        
    def put_win(self, uid, data):
        #点炮胡
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            return
        elif uid not in stop_pop_user.split(","):
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            return
        last_put_user = self.room['last_put_user']
        last_put_player = Player(last_put_user, self.bid, self.rid)
        card = last_put_player.out_card.members[-1]
        logging.info("last_put_user:%s, card:%s" % (last_put_user, card))
        p = Player(uid, self.bid, self.rid)
        if not self.check_put_win(p, card):
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            return
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        all_horse_card = []
        horse_card = []
        horse_num = 0
        horse = self.room['horse']
        if horse:
            horse = int(horse)
            all_horse_card, horse_card = self.get_horse(horse, uid)
            horse_num = len(horse_card)
        else:
            horse = 0
        current_card = p.current_card.members
        data['card'] = card
        win_type_list = self.get_put_win_type(p, card)
        logging.info(u"点炮胡:%s" % str(win_type_list))
        if self.room['bar_get_card'] == card:
            #杠上开花
            win_type_list.append("bar_put_win")
        room_left_card = self.current_card.members
        if not room_left_card or len(room_left_card) == horse:
            #海底捞月
            win_type_list.append("haidi_put_win")
        members = self.members
        for member in members:
            if member != str(uid):
                player = Player(member, self.bid, self.rid)
                current_card = player.current_card.members
                if self.check_bar(current_card, card):
                    win_type_list.append("pair_bar_win")
        
        base_score = 1
        score = self.get_win_score(win_type_list)
        if score > 12:
            score = 12
        win_score = score + horse_num * 2
        logging.info(u"房间:%s用户%s点炮胡,中%s马,得%s分" % (self.rid, uid, horse_num, win_score))
        win_type_list = self.trans_win_type(win_type_list)
        logging.info(u"点炮胡:%s" % str(win_type_list))
        #grab_bar_duty = self.room['grab_bar_duty']
        p.score['score'] = int(p.score['score']) + win_score
        mid = self.incr_mid()
        for member in members:
            if member != uid:
                player = Player(member, self.bid, self.rid)
                # 抢杠胡全包
                if member == last_put_user:
                    player.score['score'] = int(player.score['score']) - win_score
                    logging.info(u"房间:%s用户%s点炮胡,中%s马,点炮全包:%s, 扣%s分" % (self.rid, uid, horse_num, last_put_user, win_score))
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "card":card, "tips":[], "rid":self.rid, "uid":uid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}})
        self.game_over(uid, card, all_horse_card, horse_card, horse_num, win_type="put_win", win_type_list=win_type_list)
        
    def pair_bar_win(self, uid, data):
        # 抢杠胡,杠家全包,退还之前杠的分数
        stop_pop_user = self.room['stop_pop_user']
        if not stop_pop_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            return
        elif stop_pop_user != uid:
            logging.error(u"玩家%s有提示, 不该%s操作" % (stop_pop_user, uid))
            return
        #card = data['card']
        bar_uid = self.room['last_get_user']
        bar_player = Player(bar_uid, self.bid, self.rid)
        white_bar_member = bar_player.white_bar.members
        if white_bar_member:
            card = white_bar_member[-1]
        else:
            card = data.get("card", "")
        p = Player(uid, self.bid, self.rid)
        if not self.check_win(p, card):
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            return
        all_horse_card = []
        horse_card = []
        horse_num = 0
        horse = self.room['horse']
        if horse:
            horse = int(horse)
            all_horse_card, horse_card = self.get_horse(horse, uid)
            horse_num = len(horse_card)
        else:
            horse = 0
        win_type_list = self.get_win_type(p, card)
        room_left_card = self.current_card.members
        if not room_left_card or len(room_left_card) == horse:
            #海底捞月
            win_type_list.append("haidi_win")
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        score = self.get_win_score(win_type_list)
        member_len = len(self.members)
        if score > 12:
            score = 12
        every_lose_score = score + horse_num * 2
        win_score = every_lose_score * (member_len - 1)
        win_type_list = self.trans_win_type(win_type_list)
        logging.info(u"用户%s抢杠胡,中%s马,得%s分" % (uid, horse_num, win_score))
        p.score['score'] = int(p.score['score']) + win_score
        mid = self.incr_mid()
        for member in self.members:
            if member != uid:
                player = Player(member, self.bid, self.rid)
                # 抢杠胡全包
                if member == bar_uid:
                    player.pair.append(card)
                    player.white_bar.remove(card)
                    player.score['score'] = int(player.score['score']) - win_score
                    logging.info(u"用户%s抢杠胡,中%s马,抢杠全包:%s, 扣%s分" % (uid, horse_num, bar_uid, win_score))
            
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "card":card, "tips":[], "rid":self.rid, "uid":uid, "all_horse_card":all_horse_card, "horse_card":horse_card, "horse_num":horse_num}})
        self.game_over(uid, card, all_horse_card, horse_card, horse_num, win_type="pair_bar_win", win_type_list=win_type_list)
        
class PaoDeKuai():
    '''跑得快'''
    def __init__(self, rid, bid, dealer=None):
        self.rid = str(rid)
        if dealer:
            redisco.connection.delete("r:%s:current_card" % rid)
            redisco.connection.delete("r:%s:mid" % rid)
            self.room = Hash("r:%s" % rid)
            self.room['dealer'] = dealer
            self.room['last_get_user'] = dealer
            self.room['last_put_user'] = ''
            self.room['stop_pop_user'] = ''
            self.room['stop_pop_act'] = ''
        else:
            self.room = Hash("r:%s" % rid)
        self.current_card = List("r:%s:current_card" % rid)
        self.bid = bid
        l = List("r:%s:p" % rid)
        self.members = l.members
    
    def incr_mid(self):
        return redisco.connection.incr("r:%s:mid" % self.rid)
    
    def get_card_point(self, c):
        '''获取某张扑克牌的点数'''
        return int(c)/10
    
    def trans_card(self, card):
        '''转换手牌列表,去掉花色'''
        res = []
        card.sort()
        for c in card:
            card_point = self.get_card_point(c)
            res.append(card_point)
        return res
    
    def is_pair(self, card_list):
        '''是否对子'''
        if len(card_list) == 2:
            if card_list[0] == card_list[1]:
                return True, [card_list[0]]
        return False, []
    
    def is_seq_pair(self, card_list):
        '''连对'''
        res = []
        card_list.sort()
        if len(card_list) >= 4 and len(card_list) % 2 == 0:
            for c in set(card_list):
                if card_list.count(c) != 2:
                    return False, []
                res.append(c)
            res.sort()
            start_i = res[0]
            end_i = res[-1]
            if res == range(start_i, end_i+1) and end_i < 13:
                return True, [start_i, end_i]
        return False, []
    
    def is_bomb(self, card_list):
        '''炸弹'''
        if len(card_list) == 4:
            if card_list[0] == card_list[1] and card_list[0] == card_list[2] and card_list[0] == card_list[3]:
                return True, [card_list[0]]
        return False, []
    
    def is_bomb_one(self, card_list):
        '''炸弹带1'''
        bomb_list = []
        single_list = []
        if len(card_list) == 5:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 4:
                    bomb_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(bomb_list) == 1 and len(single_list) == 1:
                return True, bomb_list
        return False, []
    
    def is_bomb_two(self, card_list):
        '''炸弹带2'''
        bomb_list = []
        single_list = []
        if len(card_list) == 6:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 4:
                    bomb_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(bomb_list) == 1 and len(single_list) == 2:
                return True, bomb_list
        return False, []
    
    def is_bomb_three(self, card_list):
        '''炸弹带3'''
        bomb_list = []
        single_list = []
        if len(card_list) == 7:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 4:
                    bomb_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(bomb_list) == 1 and len(single_list) == 3:
                return True, bomb_list
        return False, []
    
    def is_triple_without(self, card_list):
        '''三不带'''
        if len(card_list) == 3:
            if card_list[0] == card_list[1] and card_list[0] == card_list[2]:
                return True, [card_list[0]]
        return False, []
    
    def is_triple_one(self, card_list):
        '''三带一'''
        triple_list = []
        single_list = []
        if len(card_list) == 4:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 3:
                    triple_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(triple_list) == 1 and len(single_list) == 1:
                return True, triple_list
        return False, []
    
    def is_triple_two(self, card_list):
        '''三带二'''
        triple_list = []
        single_list = []
        if len(card_list) == 5:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt == 3:
                    triple_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(triple_list) == 1 and len(single_list) == 2:
                return True, triple_list
        return False, []
    
    def is_seq(self, card_list):
        '''顺子'''
        card_list.sort()
        start_i = card_list[0]
        end_i = card_list[-1]
        if card_list == range(start_i, end_i+1) and end_i < 13:
            return True, [start_i, end_i]
        return False, []
    
    def is_seq_triple(self, card_list):
        '''飞机'''
        single_list = []
        triple_list = []
        card_list.sort()
        if len(card_list) >= 6:
            for c in set(card_list):
                c_cnt = card_list.count(c)
                if c_cnt >= 3:
                    triple_list.append(c)
                else:
                    single_list.extend([c]*c_cnt)
            if len(triple_list) >= 2:
                triple_list.sort()
                start_i = triple_list[0]
                end_i = triple_list[-1]
                if triple_list == range(start_i, end_i+1) and end_i < 13 and (len(card_list)- len(triple_list) * 3) <= len(triple_list) * 2:
                    return True, [start_i, end_i]
                else:
                    seq_list = []
                    for i in range(1, len(triple_list)):
                        for j in range(len(triple_list)):
                            tmp_seq = range(triple_list[j], triple_list[j]+i)
                            if all(map(lambda x: x in triple_list, tmp_seq)):
                                seq_list.append(tmp_seq)
                    res = []
                    for seq in seq_list:
                        if len(seq) > len(res):
                            res = seq
                    if res and (len(card_list)-len(res)*3) <= len(res)*2:
                        return True, [res[0], res[-1]]
        return False, []
    
    def get_card_type(self, card):
        card_list = self.trans_card(card)
        card_len = len(card_list)
        if card_len >= 5:
            #检查是否顺子
            #检查是否三带二
            #检查是否连对
            #检查是否飞机
            #四带3
            #四带2
            #四带1
            res = self.is_seq(card_list)
            if res[0]:
                return 'seq', res[1]
            if card_len % 2 == 0:
                res = self.is_seq_pair(card_list)
                if res[0]:
                    return 'seq_pair', res[1]
            
            res = self.is_seq_triple(card_list)
            if res[0]:
                return 'seq_triple', res[1]
            
            if card_len == 5:
                res = self.is_triple_two(card_list)
                if res[0]:
                    return 'triple_two', res[1]
                res = self.is_bomb_one(card_list)
                if res[0]:
                    return 'bomb_one', res[1]
            if card_len == 6:
                res = self.is_bomb_two(card_list)
                if res[0]:
                    return 'bomb_two', res[1]
            if card_len == 7:
                res = self.is_bomb_three(card_list)
                if res[0]:
                    return 'bomb_three', res[1]
                
        elif card_len == 4:
            #检查连对
            #检查炸弹
            #检查三带一
            res = self.is_bomb(card_list)
            if res[0]:
                return 'bomb', res[1]
            res = self.is_seq_pair(card_list)
            if res[0]:
                return 'seq_pair', res[1]
            res = self.is_triple_one(card_list)
            if res[0]:
                return 'triple_one', res[1]
        elif card_len == 3:
            #三不带
            res = self.is_triple_without(card_list)
            if res[0]:
                return 'triple', res[1]
        elif card_len == 2:
            res = self.is_pair(card_list)
            if res[0]:
                return 'pair', res[1]
        elif card_len == 1:
            return 'single', card_list
        return '', []
    
    def compare_card(self, card1, card2):
        #判断card2是否比card1牌型大
        card_type2 = self.get_card_type(card2)
        card_type1 = self.get_card_type(card1)
        if card_type1[0] == card_type2[0]:
            #相同类型的牌
            if len(card1) != len(card2):
                return False
            card1_point_s = card_type1[1][0]
            card1_point_e = card_type1[1][-1]
            card2_point_s = card_type2[1][0]
            card2_point_e = card_type2[1][-1]
            if card2_point_s > card1_point_s and card2_point_e > card1_point_e:
                return True
        elif card_type2[0] == 'bomb':
            return True
        return False
    
    def get_card_by_point(self, card, card_point, num=4):
        '''取手牌中某个点数的固定数量的牌'''
        res = []
        for c in card:
            if self.get_card_point(c) == card_point and len(res) < num:
                res.append(c)
        return res
    
    def get_bomb_card(self, card, bomb_point=0):
        '''取手牌中大于bomb_point的炸弹, 为0则返回所有炸弹'''
        res = []
        tips_list = []
        card_list = self.trans_card(card)
        bomb_list = []
        for c in set(card_list):
            if card_list.count(c) == 4 and c > bomb_point:
                bomb_list.append(c)
        for bomb in bomb_list:
            tips_card = []
            for i in range(1, 5):
                tips_card.append(str(bomb * 10 + i))
            res.extend(tips_card)
            tips_list.append(tips_card)
        return res, tips_list

    def get_single_card(self, card, single_point=0):
        '''取手牌中大于single_point点数的单张牌'''
        res = []
        tips_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if c > single_point:
                rs = self.get_card_by_point(card, c)
                res.extend(rs)
                tips_card = rs[:1]
                tips_list.append(tips_card)
        return res, tips_list
    
    def get_pair_card(self, card, pair_point=0):
        '''取手牌中大于pair_point点数的对子扑克牌'''
        res = []
        tips_list = []
        pair_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) >= 2:
                if c > pair_point:
                    pair_list.append(c)
        for card_point in pair_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:2]
            tips_list.append(tips_card)
        return res, tips_list
    
    def get_seq_card(self, card, seq_s=0, num=5):
        '''获取手牌中包含大于某个点数的顺子对应的扑克牌'''
        seq_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_list.append(rs)
        card_list = self.trans_card(card)
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_list:
            if set(seq).issubset(set(card_list)):
                has_seq_set |= set(seq)
                tips_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 1)
                    tips_card.append(rs[0])
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        return res, tips_list
    
    def get_seq_pair_card(self, card, seq_s=0, num=2):
        '''取手牌中包含大于seq_s的连对'''
        seq_pair_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_pair_list.append(rs)
        card_list = self.trans_card(card)
        pair_list = []
        for c in set(card_list):
            if card_list.count(c) >= 2:
                pair_list.append(c)
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_pair_list:
            if set(seq).issubset(set(pair_list)):
                has_seq_set |= set(seq)
                tips_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 2)
                    tips_card.extend(rs)
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        return res, tips_list
    
    def get_triple_card(self, card, triple_point=0):
        '''取手牌中包含大于triple_point的3张'''
        if len(card) < 5:
            return [], []
        res = []
        tips_list = []
        triple_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) >= 3:
                if c > triple_point:
                    triple_list.append(c)
        for card_point in triple_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:3]
            with_card_list = []
            other_list = list(set(card_list) - set([card_point]))
            for c in other_list:
                rs = self.get_card_by_point(card, c, 3)
                with_card_list.extend(rs)
                    
            with_card = with_card_list[:2]
            tips_card.extend(with_card)
            tips_list.append(tips_card)
        if res:
            return card, tips_list
        return res, tips_list
    
    def get_bomb_three_card(self, card, bomb_point=0):
        '''取手牌中包含大于bomb'''
        if len(card) < 6:
            return [], []
        res = []
        tips_list = []
        bomb_list = []
        card_list = self.trans_card(card)
        for c in set(card_list):
            if card_list.count(c) >= 4:
                if c > bomb_point:
                    bomb_list.append(c)
        for card_point in bomb_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
            tips_card = rs[:4]
            with_card_list = []
            other_list = list(set(card_list) - set([card_point]))
            for c in other_list:
                rs = self.get_card_by_point(card, c, 3)
                with_card_list.extend(rs)
                    
            with_card = with_card_list[:3]
            tips_card.extend(with_card)
            tips_list.append(tips_card)
        if res:
            return card, tips_list
        return res, tips_list
    
    def get_seq_triple_card(self, card, seq_s=0, num=2):
        '''取手牌中包含大于seq_s的飞机'''
        if len(card) < 3 * num + 2*num:
            return [], []
        seq_triple_list = []
        end_c = 13 - num
        for start_c in range(seq_s+1, end_c+1):
            rs = range(start_c, start_c+num)
            seq_triple_list.append(rs)
        card_list = self.trans_card(card)
        triple_list = []
        for c in set(card_list):
            c_cnt = card_list.count(c)
            if c_cnt >= 3:
                triple_list.append(c)
        res = []
        tips_list = []
        has_seq_set = set()
        for seq in seq_triple_list:
            if set(seq).issubset(set(triple_list)):
                has_seq_set |= set(seq)
                with_card_list = []
                other_list = list(set(card_list) - set(seq))
                for c in other_list:
                    rs = self.get_card_by_point(card, c, 3)
                    with_card_list.extend(rs)
                tips_card = []
                with_card = []
                for c in seq:
                    rs = self.get_card_by_point(card, c, 3)
                    tips_card.extend(rs)
                    for i in range(2):
                        w = with_card_list.pop()
                        with_card.append(w)
                tips_card.extend(with_card)
                tips_list.append(tips_card)
        has_seq_list = list(has_seq_set)
        for card_point in has_seq_list:
            rs = self.get_card_by_point(card, card_point)
            res.extend(rs)
        if res:
            return card, tips_list
        return res, tips_list
    
    def check_validate(self, card, card_type):
        return self.get_card_type(card)[0] == card_type

    def get_valid_card(self, current_card, last_put_card, last_put_type='', last_put_point=''):
        valid_card = []
        if not last_put_type:
            last_put_type, last_put_point = self.get_card_type(last_put_card)
        if last_put_type == 'single':
            valid_card = self.get_single_card(current_card, int(last_put_point[0]))
        elif last_put_type == 'pair':
            valid_card = self.get_pair_card(current_card, int(last_put_point[0]))
        elif last_put_type == 'seq_pair':
            valid_card = self.get_seq_pair_card(current_card, int(last_put_point[0]), int(last_put_point[1])-int(last_put_point[0])+1)
        elif last_put_type == 'seq':
            valid_card = self.get_seq_card(current_card, int(last_put_point[0]), len(last_put_card))
        elif last_put_type == 'triple_two':
            valid_card = self.get_triple_card(current_card, int(last_put_point[0]))
        elif last_put_type == 'seq_triple':
            valid_card = self.get_seq_triple_card(current_card, int(last_put_point[0]), int(last_put_point[1])-int(last_put_point[0])+1)
        elif last_put_type == 'bomb_three':
            valid_card = self.get_bomb_three_card(current_card, int(last_put_point[0]))
        if last_put_type == 'bomb':
            valid_card = self.get_bomb_card(current_card, int(last_put_point[0]))
        else:
            bomb_card = self.get_bomb_card(current_card, 0)
            valid_list = bomb_card[0]
            tips_list = bomb_card[1]
            if valid_card:
                valid_card[0].extend(valid_list)
                valid_card[1].extend(tips_list)
            else:
                valid_card = bomb_card
        return valid_card
    
    def start(self):
        self.room['status'] = 'start'
        game_round = int(self.room['game_round'])
        all_card = []
        for i in range(10, 140, 10):
            for j in range(1, 5):
                all_card.append(i+j)
        #去掉3个2一个A
        card_num = self.room['card_num']
        if card_num and card_num == '15':
            for c in (114, 122, 123, 124, 132, 133, 134):
                all_card.remove(c)
        else:
            for c in (124, 132, 133, 134):
                all_card.remove(c)
                
        random.shuffle(all_card)
        random.shuffle(all_card)
        members = self.members
        all_card_num = len(all_card)
        player_cnt = len(members)
        black_three = 11
        match_id = self.room['mid']
        if match_id:
            dealer = members[game_round%player_cnt-1]
            self.room['dealer'] = dealer
        else:
            dealer = self.room['dealer']
        #第一局黑桃3先出
        
        player_card = []
        every_player_num = all_card_num/3
        for uid in members:
            player_card.append({"uid":uid, "left_num":every_player_num})
        
        first_card = []
        black_three_first = 'n'
        user_card = {}
        for uid in members:
            card = []
            for i in range(every_player_num):
                card.append(all_card.pop())
            card.sort()
            card.reverse()
            if not match_id and black_three in card and game_round == 1:
                dealer = uid
                self.room['dealer'] = dealer
                black_three_first = self.room['black_three_first']
                if black_three_first == 'y':
                    first_card = ['11',]
                else:
                    black_three_first = 'n'
            user_card[uid] = card
            
        for uid in members:
            mid = self.incr_mid()
            player = Player(uid, self.bid, self.rid, True)
            card = user_card[uid]
            #player.current_card.clear()
            #rsecond = random.randint(10, 30)
            #time.sleep(rsecond/1000.0)
            player.current_card.clear()
            player.current_card.extend(card)
            card_list = [str(x) for x in card]
            nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"act":"game_start", "status":"start", "left_card":0, "rid":self.rid, "mid":mid, "dealer":dealer, "card":card_list, "game_round":self.room['game_round'], "all_round":self.room['all_round'], "player_card":player_card}})
        
        self.room['last_put_user'] = ''
        self.room['last_put_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_put_point'] = ''
        self.room['stop_pop_user'] = dealer
        self.current_card.clear()
        logging.info(u"跑得快房间rid:%s,game_round:%s,发牌结束,通知%s出牌" % (self.rid, self.room['game_round'], dealer))
        self.notify_keep_put(dealer)
        
    def notify_keep_put(self, uid):
        #last_put_user = self.room['last_put_user']
        self.room['stop_pop_user'] = uid
        self.room['last_get_user'] = uid
        self.room['last_put_user'] = ''
        self.room['last_put_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_put_point'] = ''
        #mid = self.incr_mid()
        members = self.members
        player_cnt = len(members)
        max_single = 'n'
        #下家报单可以不出最大的牌
        match_id = self.room['mid']
        user_seat = members.index(uid)
        next_seat = (user_seat+1) % player_cnt
        next_user = members[next_seat]
        next_player = Player(next_user, self.bid, self.rid)
        if len(next_player.current_card.members) == 1:
            max_single = 'y'
                
        for member in members:
            if member == uid:
                tips_list = []
                player = Player(uid, self.bid, self.rid)
                all_card = player.current_card.members
                card_type, card_point = self.get_card_type(all_card)
                #if card_type and card_type not in ('bomb_one', 'bomb_two', 'bomb_three'):
                bomb_res, bomb_tips = self.get_bomb_card(all_card)
                if card_type and not bomb_res:
                    tips_list.append(all_card)
                else:
                    current_card = sorted(all_card, key=lambda x:int(x), reverse=True)
                    tips_list.append([current_card[0]])
            else:
                all_card = []
                tips_list = []
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"turn_put", "put_type":"free", "max_single":max_single, "uid":uid, "valid_list":all_card, "rid":self.rid, "tips_list":tips_list, "last_put_card":[], "last_put_type":"", "last_put_point":[]}})
        
        if match_id:
            current_user = Hash("%s_%s" % (self.bid, uid))
            if current_user['online'] != 'y' or current_user['rid'] != self.rid:
                self.auto_put(uid)
            
    def notify_next_user(self, pre_user):
        members = self.members
        pre_user_seat = members.index(pre_user)
        next_user_seat = (pre_user_seat + 1) % len(members)
        next_user = members[next_user_seat]
        self.room['stop_pop_user'] = next_user
        last_put_user = self.room['last_put_user']
        if not last_put_user or next_user == last_put_user:
            #首次出牌或者过一圈没人能打起
            self.notify_keep_put(next_user)
            return
        else:
            max_single = 'n'
            last_put_card = self.room['last_put_card'].split(",")
            last_put_type = self.room['last_put_type']
            last_put_point = self.room['last_put_point'].split(",")
            if last_put_point:
                last_put_point = [int(x) for x in last_put_point]
            #判断下家能否打牌,没有打牌则自动发送要不起,否则发送出牌通知
            #last_put_type, last_put_point = self.get_card_type(last_put_card)
            p = Player(next_user, self.bid, self.rid)
            current_card = p.current_card.members
            logging.info(u"判断下家是否有牌:%s, last_put_card:%s, type:%s, point:%s" % (next_user, str(last_put_card), last_put_type, str(last_put_point)))
            valid_card = self.get_valid_card(current_card, last_put_card, last_put_type, last_put_point)
            #mid = self.incr_mid()
            match_id = self.room['mid']
            if last_put_type == 'single' and valid_card:
                
                next_next_user_seat = (next_user_seat+1) % len(members)
                next_next_user = members[next_next_user_seat]
                next_next_player = Player(next_next_user, self.bid, self.rid)
                logging.info(u"上家出的单牌, 检查下家%s是否报单, %s" % (next_next_user, str(next_next_player.current_card.members)))
                if len(next_next_player.current_card.members) == 1:
                    max_single = 'y'
                    logging.info(u"下家%s报单" % next_next_user)
                    
            for member in members:
                if member == next_user:
                    valid_list, tips_list = valid_card
                    logging.info(u"下家%s可出的牌有:valid_list:%s, tips_list:%s" % (member, str(valid_list), str(tips_list)))
                    if max_single == 'y':
                        #v_list = valid_list
                        #valid_list = sorted(valid_list, key=lambda x:int(x))[-1:]
                        #if len(v_list) == 4:
                        #    bomb_card = self.get_bomb_card(current_card, 0)
                        #    if bomb_card[0]:
                        #        valid_list = v_list
                        #tips_list = sorted(tips_list, key=lambda x:sum([int(y) for y in x]))[-1:]
                        valid_list = sorted(valid_list, key=lambda x:int(x))
                        tips_list = sorted(tips_list, key=lambda x:sum([int(y) for y in x]))
                    #logging.info(u"下家%s可出的牌有:%s" % (member, str(tips_list)))
                else: 
                    #logging.info(u"=============member:%s,next_user:%s" % (member, next_user))
                    valid_list, tips_list = [], []
                nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"turn_put", "put_type":"follow", "max_single":max_single, "uid":next_user, "rid":self.rid, "valid_list":valid_list, "tips_list":tips_list, "last_put_card":last_put_card, "last_put_type":last_put_type, "last_put_point":last_put_point}})
            
            if match_id:
                current_user = Hash("%s_%s" % (self.bid, next_user))
                if current_user['online'] != 'y' or current_user['rid'] != self.rid:
                    self.auto_put(next_user)
    
    def pass_card(self, uid, data={}):
        stop_pop_user = self.room['stop_pop_user']
        if uid != stop_pop_user:
            logging.error(u"pass,该%s打牌,不该%s" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        members = self.members
        mid = self.incr_mid()
        for member in members:
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"pass", "mid":mid, "uid":uid, "rid":self.rid}})
        self.notify_next_user(uid)
        
    def put_card(self, uid, data):
        uid = str(uid)
        stop_pop_user = self.room['stop_pop_user']
        if uid != stop_pop_user:
            logging.error(u"该%s出牌,不该%s" % (stop_pop_user, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        card = data['card']
        if not isinstance(card, list):
            card = card.split(",")
        put_card_type = self.get_card_type(card)
        logging.info(u"跑得快检查用户牌型%s,%s" % (put_card_type[0], put_card_type[1]))
        card_type = put_card_type[0]
        if not card_type:
            #牌型不符合
            logging.error(u"%s出牌不符合规范,%s" % (uid, ",".join(card)))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return 
        
        current_player = Player(uid, self.bid, self.rid)
        user_current_card = current_player.current_card.members
        
        match_id = self.room['mid']
        double_card_num = self.room['card_num']
        if not double_card_num:
            double_card_num = 16
        else:
            double_card_num = int(double_card_num)
        if not match_id and len(user_current_card) == double_card_num:
            black_three_first = self.room['black_three_first']
            game_round = int(self.room['game_round'])
            dealer = self.room['dealer']
            if black_three_first == 'y' and game_round == 1 and str(uid) == dealer:
                black_three = '11'
                if black_three not in card:
                    logging.error(u"首局%s出牌必须包含黑桃3,%s" % (uid, self.rid))
                    return
                    
        for c in card:
            if c not in user_current_card:
                logging.error(u"出牌异常,用户%s没有该手牌,%s" % (uid, c))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
            elif card.count(c) > 1:
                logging.error(u"出牌异常,用户%s该牌重复%s" % (uid, c))
                return
        if card_type in ('triple', 'triple_one', 'bomb_two', 'bomb_one'):
            if len(user_current_card) != len(card):
                logging.error(u"出牌异常,用户%s只有最后一手才能出三带一和不带%s" % (uid, str(card)))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
        elif card_type == 'seq_triple':
            seq_s, seq_e = put_card_type[1]
            if len(user_current_card) != len(card) and len(card) != (seq_e - seq_s + 1)*5:
                logging.error(u"出牌异常,用户%s只有最后一手才能飞机少带%s" % (uid, str(card)))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
            
        last_put_type = self.room['last_put_type']
        last_put_user = self.room['last_put_user']
        last_put_point = self.room['last_put_point']
        last_put_card = self.room['last_put_card']
        members = self.members
        if last_put_card:
            #跟上家的牌
            put_type = 'follow'
            card1 = last_put_card.split(",")
            if not self.compare_card(card1, card):
                logging.error(u"出牌异常,用户%s出牌牌不能大过上家,%s" % (uid, ",".join(card)))
                get_last_data('', self.bid, uid, {"rid":self.rid})
                return
        else:
            #自由出牌
            put_type = 'free'
        
        if not match_id:
            user_seat = members.index(uid)
            next_seat = (user_seat+1) % len(members)
            next_user = members[next_seat]
            next_player = Player(next_user, self.bid, self.rid)
            next_player_card = next_player.current_card.members
            if len(next_player_card) == 1 and card_type == 'single':
                valid_card = self.get_single_card(current_player.current_card.members, int(put_card_type[1][0]))
                
                if valid_card[0]:
                    logging.error(u"出牌异常,用户%s出牌%s,必须出最大的牌, %s" % (uid, ",".join(card), ",".join(current_player.current_card.members)))
                    get_last_data('', self.bid, uid, {"rid":self.rid})
                    return
        
        for c in card:
            current_player.current_card.remove(c, 1)
            current_player.out_card.append(c)
            #self.current_card.append(c)
        
        self.room['last_put_card'] = ",".join(card)
        self.room['last_put_type'] = card_type
        self.room['last_put_point'] = ",".join([str(x) for x in put_card_type[1]])
        self.room['last_put_user'] = uid
        
        user_left_card = current_player.current_card.members
        left_num = len(user_left_card)
        win_score = 0
        
        if match_id:
            #比赛杠没有分
            all_round = int(self.room['all_round'])
            game_round = int(self.room['game_round'])
            base_score = get_match_base_score(self.bid, match_id, all_round, game_round, self.rid)
        else:
            base_score = 1
        
        if last_put_type == 'bomb':
            for member in members:
                player = Player(member, self.bid, self.rid)
                if member == last_put_user:
                    current_player.dark_bar.remove(last_put_card.split(",")[0])
                    player.score['score'] = int(player.score['score']) - 20*base_score
                else:
                    player.score['score'] = int(player.score['score']) + 10*base_score
            
        mid = self.incr_mid()
        for member in members:
            if card_type == 'bomb':
                if member == str(uid):
                    win_score = 20 * base_score
                    current_player.score['score'] =  int(current_player.score['score']) + win_score
                    current_player.dark_bar.append(card[0])
                else:
                    win_score = -10 * base_score
                    player = Player(member, self.bid, self.rid)
                    player.score['score'] = int(player.score['score']) + win_score
                    
            if member == str(uid):
                left_card = user_left_card
            else:
                left_card = []
                
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"put_card", "mid":mid, "put_type":put_type, "left_card":left_card, "left_num":left_num, "uid":uid, "rid":self.rid, "card":card, "card_type":card_type}})
        
        if user_left_card:
            card_warning = self.room['card_warning']
            if not card_warning:
                card_warning = 1
            else:
                card_warning = int(card_warning)
            if left_num <= card_warning:
                for member in members:
                    nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"card_warning", "left_num":left_num, "uid":uid, "rid":self.rid}})
            self.notify_next_user(uid)
        else:
            duty_uid = ''
            if card_type == 'single' and put_type == 'follow':
                #报单没有出最大的单牌导致放走后包赔
                card1 = last_put_card.split(",")
                #last_put_seat = members.index(last_put_user)
                my_seat = members.index(uid)
                if members[my_seat - 1] == last_put_user:
                #if (my_seat - last_put_seat)%len(members) == 1:
                    last_put_player = Player(last_put_user, self.bid, self.rid)
                    all_card = last_put_player.current_card.members
                    logging.info(u"%s报单出完了检查用户%s是否该包赔:%s,%s" % (uid, last_put_user, str(all_card), str(last_put_point)))
                    #valid_card = self.get_single_card(all_card, int(last_put_point))
                    valid_bomb_card = self.get_bomb_card(all_card)
                    #if valid_card[0] or valid_bomb_card[0]:
                    if valid_bomb_card[0]:
                        duty_uid = last_put_user
                        logging.info(u"跑得快%s玩家%s没有出最大的牌,包赔" % (self.rid, last_put_user))
            self.game_over(uid, False, duty_uid)
    
    def auto_put(self, uid):
        uid = str(uid)
        stop_pop_user = self.room['stop_pop_user']
        if uid != stop_pop_user:
            logging.error(u"该%s出牌,不该%s" % (stop_pop_user, uid))
            return
        last_put_user = self.room['last_put_user']
        p = Player(uid, self.bid, self.rid)
        if not last_put_user or uid == last_put_user:
            #首次出牌或者过一圈没人能打起
            current_card = sorted(p.current_card.members, key=lambda x:int(x))
            card = current_card[-1]
            data = {"card":[card]}
            self.put_card(uid, data)
            return
        else:
            time.sleep(0.01)
            last_put_card = self.room['last_put_card'].split(",")
            last_put_type = self.room['last_put_type']
            last_put_point = self.room['last_put_point'].split(",")
            current_card = p.current_card.members
            valid_list, tips_list = self.get_valid_card(current_card, last_put_card, last_put_type, last_put_point)
            if tips_list:
                card = tips_list[0]
                data = {"card":card}
                self.put_card(uid, data)
            else:
                self.pass_card(uid)
                
    def game_over(self, winner='', from_dissmiss=False, duty_uid=''):
        #time.sleep(0.5)
        if from_dissmiss:
            from_dissmiss = "y"
        else:
            from_dissmiss = "n"
        dealer = self.room['dealer']
        db = dao.Game_DB()
        player_card = []

        rules = {}
        #room_info = db.get_room(self.rid, self.bid)
        #gid = room_info.get("gid")
        gid = self.room['gid']
        if gid:
            rows = db.game_rule(gid)
        else:
            rows = db.room_rule(self.rid)
            gid = ""
        for row in rows:
            k = row['param']
            v = row['value']
            rules[k] = v
        game_round = self.room['game_round']
        if game_round:
            game_round = int(game_round)
        else:
            game_round = 1
            
        all_round = self.room['all_round']
        if all_round:
            all_round = int(all_round)
        else:
            all_round = 1
        
        match_id = self.room['mid']
        if match_id:
            #比赛杠没有分
            base_score = get_match_base_score(self.bid, match_id, all_round, game_round, self.rid)
        else:
            base_score = 1
        
        win_score = 0
        if winner:
            for uid in self.members:
                if uid != winner:
                    p = Player(uid, self.bid, self.rid)
                    left_card_num = p.current_card.members
                    if len(left_card_num) > 1:
                        lose_score = len(left_card_num) * base_score
                        double_card_num = self.room['card_num']
                        if not double_card_num:
                            double_card_num = 16
                        else:
                            double_card_num = int(double_card_num)
                        if len(left_card_num) == double_card_num:
                            lose_score *= 2
                        win_score += lose_score
                        if duty_uid:
                            duty_player = Player(duty_uid, self.bid, self.rid)
                            duty_player.score['score'] = int(duty_player.score['score']) - lose_score
                            duty_player.score['win_score'] = "-%s" % lose_score
                            logging.info(u"跑得快%s玩家%s没有出最大的牌,包赔====" % (self.rid, duty_uid))
                        else:
                            p.score['score'] = int(p.score['score']) - lose_score
                            p.score['win_score'] = "-%s" % lose_score
            p = Player(winner, self.bid, self.rid)
            p.score['score'] =  int(p.score['score']) + win_score
            p.score['win_score'] = win_score
            
        for uid in self.members:
            if not uid:
                continue
            p = Player(uid, self.bid, self.rid)
            # 重置玩家状态,和计算分数
            dark_bar = p.dark_bar.members
            p_data = {"uid":uid, "win_score":p.score['win_score'], "score":p.score['score'], "white_bar":[], "pair":[], "out_card":[], "current_card":p.current_card.members, "dark_bar":dark_bar}
            if not winner:
                score = 0
                p_data['score'] = "0"
            else:
                score = int(p.score['score'])
            if dealer == uid:
                is_dealer = "y"
            else:
                is_dealer = "n"
            p_data['is_dealer'] = is_dealer
            db.update_player(self.rid, uid, score, 0)
            db.commit()
            player_info = db.get_player(self.rid, uid)
            p_data['user_score'] = player_info['score']
            player_card.append(p_data)
            
            if uid == winner:
                is_win = 1
            else:
                is_win = 0
            db.add_room_log(match_id, gid, self.rid, game_round, uid, score, 0, len(dark_bar), is_dealer, is_win, 0, '')
            db.commit()
        #比赛的牌局统一规则
        game_type = self.room['game_type']
        if not game_type:
            game_type = ''
        #match_id = self.room['mid']
        if match_id:
            if game_type == 'pdk':
                rules = {"must_put":"y", "release_duty":"y", "closed_double":"y"}
            else:
                rules = {"horse":0, "grab_bar_win":"y", "grab_bar_duty":"y", "bar_win_duty":"n", "seven_pair_win":"y"}
        else:
            match_id = ""
        
        
        mid = self.incr_mid()
        for uid in self.members:
            if not uid:
                continue
            pub_data = {"b":self.bid, "u":str(uid), "t":"game", "d":{"match_id":match_id, "gid":gid, "rules":rules, "win_type":"", "from_dissmiss":from_dissmiss, "dealer":self.room['dealer'], "game_round":game_round, "player_card":player_card, "mid":mid, "act":"game_over", "winner":winner, "card":"", "rid":self.rid, "all_horse_card":[], "horse_card":[], "horse_num":0}}
            nsq_pub(pub_data)
            db.save_game_over(self.rid, game_round, "game_over", uid, json_encode(pub_data))
            db.commit()
            try:
                if winner == uid:
                    win_round = 1
                else:
                    win_round = 0
                if db.has_user_stat(self.bid, uid, game_type):
                    db.update_user_stat(self.bid, uid, game_type, win_round)
                else:
                    db.add_user_stat(self.bid, uid, game_type, win_round, 0)
            except:
                logging.error(u"统计用户生涯错误:%s" % uid, exc_info=True)
        logging.info(u"房间%s牌局%s第%s局结束" % (self.rid, game_type, game_round))
        if winner:
            self.room['dealer'] = winner
        
        self.room['status'] = 'over'
        self.room['stop_pop_user'] = ''
        self.room['last_put_user'] = ''
        self.room['last_get_card'] = ''
        self.room['last_put_type'] = ''
        self.room['last_get_point'] = ''
        
        db.game_over(self.rid, game_round)
        db.commit()
        if match_id:
            nsq_pub({"b":self.bid, "u":"", "t":"game", "d":{"all_round":all_round, "match_id":match_id, "rules":rules, "win_type":"", "from_dissmiss":from_dissmiss,"dealer":self.room['dealer'], "game_round":self.room['game_round'], "player_card":player_card, "mid":mid, "act":"game_over", "winner":winner, "card":"", "rid":self.rid, "all_horse_card":[], "horse_card":[], "horse_num":0}}, "match_club")
        self.room['game_round'] = game_round + 1
        if all_round <= game_round:
            self.dismiss(act='room_over')
        else:
            if match_id:
                exp_time = (datetime.datetime.now() + datetime.timedelta(seconds=5)).strftime("%Y-%m-%d %H:%M:%S")
                db.add_cron(self.bid, "auto_ready", self.rid, 0, exp_time)
                db.commit()
        
    def dismiss(self, act='room_over'):
        #time.sleep(0.5)
        db = dao.Game_DB()
        player_data = {}
        player_stat = []
        if not self.room['status']:
            logging.info(u"房间结束,未开始:%s" % self.rid)
            deduct_flag = False
            winner = ""
            for uid in self.members:
                player_stat.append({"uid":uid,"horse":0,"dark_bar":0,"white_bar":0,"score":0,"win_num":0})
        else:
            p_stat = db.player_stat(self.rid)
            for ps in p_stat:
                ps['horse'] = int(ps['horse'])
                ps['dark_bar'] = int(ps['dark_bar'])
                ps['white_bar'] = int(ps['white_bar'])
                ps['score'] = int(ps['score'])
                ps['win_num'] = int(ps['win_num'])
                
                ps['max_score'] = int(ps['max_score'])
                ps['lose_num'] = int(ps['lose_num'])
                ps['bomb'] = int(ps['dark_bar'])
                player_data[str(ps['uid'])] = ps
            deduct_flag = True
            if p_stat:
                winner = p_stat[-1]['uid']
            else:
                winner = ""
            # 排序最后一家为大赢家
            player_stat = p_stat
         
        room_info = db.get_room(self.rid, self.bid)
        admin = room_info['admin']
        match_id = room_info['mid']
        gid = room_info['gid']
        if not gid:
            gid = 0
        for ps in player_stat:
            if ps['uid'] == winner:
                is_winner = 'y'
            else:
                is_winner = 'n'
            db.add_room_stat(match_id, gid, self.rid, ps['uid'], ps['score'], is_winner)
            db.commit()
        if not match_id:
            #比赛的房间不发送room_over
            for uid in self.members:
                if not uid:
                    continue
                pub_data = {"b":self.bid, "u":str(uid), "t":"game", "d":{"act":"room_over", "rid":self.rid, "player_stat":player_stat, "winner":winner, "admin":admin}}
                db.save_game_over(self.rid, 0, "room_over", uid, json_encode(pub_data))
                db.commit()
                nsq_pub(pub_data)
                
        else:
            #比赛房间不扣房卡
            deduct_flag = False
        db.dismiss_room(self.rid)
        db.commit()
        game_type = self.room['game_type']
        #gid = self.room['gid']
        if match_id or gid:
            nsq_pub({"b":self.bid, "u":"", "t":"game", "d":{"game_type":game_type, "match_id":match_id, "gid":gid, "act":"room_over", "rid":self.rid, "player_stat":player_stat, "winner":winner, "admin":admin}}, "match_club")
            
        #if deduct_flag:
        #    card = room_info['card']
        #    db.deduct_card(self.bid, admin, card)
        #    db.commit()
        #    nsq_pub({"act":"deduct_card", "bid":self.bid, "uid":admin, "card":card, "rid":self.rid}, "total")
        #    logging.info(u"房间%s解散成功,扣除房卡, bid:%s,uid:%s,card:%s" % (self.rid, self.bid, admin, card))
        #else:
        #    logging.info(u"房间%s解散成功,游戏无需扣房卡" % self.rid)
        for member in self.members:
            member_player = Player(member, self.bid, self.rid)
            member_player.clear()
        redisco.connection.delete("r:%s:current_card" % self.rid)
        redisco.connection.delete("r:%s:out_card" % self.rid)
        redisco.connection.delete("r:%s" % self.rid)
        redisco.connection.delete("r:%s:mid" % self.rid)
        redisco.connection.delete("r:%s:p" % self.rid)
    
if __name__ == "__main__":
    tdh = MaJiang('100016', 'szjt')
    tdh.pass_card('', '')
    

